Update CHANGELOG.md

This commit is contained in:
InsanusMokrassar 2021-06-03 23:34:11 +06:00
parent 39fa36426f
commit 3829e04b0c
10 changed files with 38 additions and 28 deletions

View File

@ -20,8 +20,13 @@
* `RecordAudioAction` and `UploadAudioAction` (and all related to these actions functionality) have been removed * `RecordAudioAction` and `UploadAudioAction` (and all related to these actions functionality) have been removed
* `TextSource` interface and all related things have been replaced * `TextSource` interface and all related things have been replaced
* `CallbackQuery` interface and all its extenders/implementers become `sealed` * `CallbackQuery` interface and all its extenders/implementers become `sealed`
* `ChatMember` become `sealed` * `InputMedia` interface and all its extenders/implementers become `sealed`
* `ParseMode` interface and all its extenders/implementers become `sealed`
* `ChatMember` becomes `sealed`
* `KeyboardMarkup` becomes `sealed`
* `LeftChatMember` and `MemberChatMember` become interfaces. All their code were replaced to the `*Impl` classes * `LeftChatMember` and `MemberChatMember` become interfaces. All their code were replaced to the `*Impl` classes
* Most of `sealed` classes have been modified to be interfaces
* Most serializers becomes public, but they are still `RistFeature`
## 0.34.1 ## 0.34.1

View File

@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.requests.abstracts.SimpleRequest
import dev.inmo.tgbotapi.types.* import dev.inmo.tgbotapi.types.*
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.serializers.InlineQueryResultSerializer import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.serializers.InlineQueryResultSerializer
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.utils.RiskFeature import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
@ -34,7 +35,7 @@ data class AnswerInlineQuery(
get() = serializer() get() = serializer()
} }
fun dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.createAnswer( fun InlineQuery.createAnswer(
results: List<InlineQueryResult> = emptyList(), results: List<InlineQueryResult> = emptyList(),
cachedTime: Int? = null, cachedTime: Int? = null,
isPersonal: Boolean? = null, isPersonal: Boolean? = null,

View File

@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.types package dev.inmo.tgbotapi.types
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import dev.inmo.tgbotapi.utils.RiskFeature
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
@ -79,6 +80,7 @@ data class CommonInviteLink(
get() = expireDate ?.asDate get() = expireDate ?.asDate
} }
@RiskFeature
object ChatInviteLinkSerializer : KSerializer<ChatInviteLink> { object ChatInviteLinkSerializer : KSerializer<ChatInviteLink> {
override val descriptor: SerialDescriptor override val descriptor: SerialDescriptor
get() = RawChatInviteLink.serializer().descriptor get() = RawChatInviteLink.serializer().descriptor

View File

@ -40,6 +40,8 @@ val String.asChatType
ChatType.ChannelChatType.stringified -> ChatType.ChannelChatType ChatType.ChannelChatType.stringified -> ChatType.ChannelChatType
else -> ChatType.UnknownChatType(this) else -> ChatType.UnknownChatType(this)
} }
@RiskFeature
object ChatTypeSerializer : KSerializer<ChatType> { object ChatTypeSerializer : KSerializer<ChatType> {
override val descriptor: SerialDescriptor = String.serializer().descriptor override val descriptor: SerialDescriptor = String.serializer().descriptor
override fun deserialize(decoder: Decoder): ChatType { override fun deserialize(decoder: Decoder): ChatType {

View File

@ -35,6 +35,7 @@ val encryptedElementsClassesByTypes = mapOf(
val EncryptedPassportElement.type: String val EncryptedPassportElement.type: String
get() = encryptedElementsClassesByTypes.keys.firstOrNull { encryptedElementsClassesByTypes.getValue(it).klass.isInstance(this) } ?: "unknown" get() = encryptedElementsClassesByTypes.keys.firstOrNull { encryptedElementsClassesByTypes.getValue(it).klass.isInstance(this) } ?: "unknown"
@RiskFeature
object EncryptedElementSerializer : KSerializer<EncryptedPassportElement> { object EncryptedElementSerializer : KSerializer<EncryptedPassportElement> {
private val jsonSerializer = JsonObject.serializer() private val jsonSerializer = JsonObject.serializer()
override val descriptor: SerialDescriptor = jsonSerializer.descriptor override val descriptor: SerialDescriptor = jsonSerializer.descriptor

View File

@ -3,6 +3,7 @@ package dev.inmo.tgbotapi.extensions.api.answers
import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.answers.AnswerInlineQuery import dev.inmo.tgbotapi.requests.answers.AnswerInlineQuery
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.InlineQueryResult
import dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery
import dev.inmo.tgbotapi.types.InlineQueryIdentifier import dev.inmo.tgbotapi.types.InlineQueryIdentifier
suspend fun TelegramBot.answerInlineQuery( suspend fun TelegramBot.answerInlineQuery(
@ -18,7 +19,7 @@ suspend fun TelegramBot.answerInlineQuery(
) )
suspend fun TelegramBot.answerInlineQuery( suspend fun TelegramBot.answerInlineQuery(
inlineQuery: dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery, inlineQuery: InlineQuery,
results: List<InlineQueryResult> = emptyList(), results: List<InlineQueryResult> = emptyList(),
cachedTime: Int? = null, cachedTime: Int? = null,
isPersonal: Boolean? = null, isPersonal: Boolean? = null,

View File

@ -12,7 +12,7 @@ private suspend fun <O> BehaviourContext.waitInlineQueries(
count: Int = 1, count: Int = 1,
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
errorFactory: NullableRequestBuilder<*> = { null }, errorFactory: NullableRequestBuilder<*> = { null },
mapper: suspend dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.() -> O? mapper: suspend InlineQuery.() -> O?
): List<O> = expectFlow( ): List<O> = expectFlow(
initRequest, initRequest,
count, count,
@ -22,7 +22,7 @@ private suspend fun <O> BehaviourContext.waitInlineQueries(
}.toList().toList() }.toList().toList()
private suspend inline fun <reified T : dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery> BehaviourContext.waitInlines( private suspend inline fun <reified T : InlineQuery> BehaviourContext.waitInlines(
count: Int = 1, count: Int = 1,
initRequest: Request<*>? = null, initRequest: Request<*>? = null,
noinline errorFactory: NullableRequestBuilder<*> = { null }, noinline errorFactory: NullableRequestBuilder<*> = { null },

View File

@ -7,7 +7,7 @@ import dev.inmo.tgbotapi.extensions.utils.asInlineQueryUpdate
import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat import dev.inmo.tgbotapi.extensions.utils.extensions.sourceChat
import dev.inmo.tgbotapi.types.InlineQueries.query.* import dev.inmo.tgbotapi.types.InlineQueries.query.*
internal suspend inline fun <reified T : dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery> BehaviourContext.onInlineQuery( internal suspend inline fun <reified T : InlineQuery> BehaviourContext.onInlineQuery(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
noinline additionalFilter: (suspend (T) -> Boolean)? = null, noinline additionalFilter: (suspend (T) -> Boolean)? = null,
noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, T> noinline scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, T>
@ -36,7 +36,7 @@ internal suspend inline fun <reified T : dev.inmo.tgbotapi.types.InlineQueries.q
suspend fun BehaviourContext.onAnyInlineQuery( suspend fun BehaviourContext.onAnyInlineQuery(
includeFilterByChatInBehaviourSubContext: Boolean = true, includeFilterByChatInBehaviourSubContext: Boolean = true,
additionalFilter: (suspend (InlineQuery) -> Boolean)? = null, additionalFilter: (suspend (InlineQuery) -> Boolean)? = null,
scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery> scenarioReceiver: BehaviourContextAndTypeReceiver<Unit, InlineQuery>
) = onInlineQuery(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver) ) = onInlineQuery(includeFilterByChatInBehaviourSubContext, additionalFilter, scenarioReceiver)

View File

@ -20,8 +20,7 @@ import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.* import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.abstracts.results.voice.*
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.* import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.*
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputMessageContent import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputMessageContent
import dev.inmo.tgbotapi.types.InlineQueries.query.BaseInlineQuery import dev.inmo.tgbotapi.types.InlineQueries.query.*
import dev.inmo.tgbotapi.types.InlineQueries.query.LocationInlineQuery
import dev.inmo.tgbotapi.types.InputMedia.* import dev.inmo.tgbotapi.types.InputMedia.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.* import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.types.actions.* import dev.inmo.tgbotapi.types.actions.*
@ -924,19 +923,19 @@ inline fun BotAction.asUploadVideoNoteAction(): UploadVideoNoteAction? = this as
inline fun BotAction.requireUploadVideoNoteAction(): UploadVideoNoteAction = this as UploadVideoNoteAction inline fun BotAction.requireUploadVideoNoteAction(): UploadVideoNoteAction = this as UploadVideoNoteAction
@PreviewFeature @PreviewFeature
inline fun dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.asBaseInlineQuery(): BaseInlineQuery? = inline fun InlineQuery.asBaseInlineQuery(): BaseInlineQuery? =
this as? BaseInlineQuery this as? BaseInlineQuery
@PreviewFeature @PreviewFeature
inline fun dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.requireBaseInlineQuery(): BaseInlineQuery = inline fun InlineQuery.requireBaseInlineQuery(): BaseInlineQuery =
this as BaseInlineQuery this as BaseInlineQuery
@PreviewFeature @PreviewFeature
inline fun dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.asLocationInlineQuery(): LocationInlineQuery? = inline fun InlineQuery.asLocationInlineQuery(): LocationInlineQuery? =
this as? LocationInlineQuery this as? LocationInlineQuery
@PreviewFeature @PreviewFeature
inline fun dev.inmo.tgbotapi.types.InlineQueries.query.InlineQuery.requireLocationInlineQuery(): LocationInlineQuery = inline fun InlineQuery.requireLocationInlineQuery(): LocationInlineQuery =
this as LocationInlineQuery this as LocationInlineQuery
@PreviewFeature @PreviewFeature

View File

@ -2,8 +2,7 @@
package dev.inmo.tgbotapi.extensions.utils.formatting package dev.inmo.tgbotapi.extensions.utils.formatting
import dev.inmo.tgbotapi.types.MessageEntity.textsources.MutableTextSourcesList import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSourcesList
import dev.inmo.tgbotapi.types.User import dev.inmo.tgbotapi.types.User
fun buildEntities(init: EntitiesBuilder.() -> Unit): TextSourcesList = EntitiesBuilder().apply(init).build() fun buildEntities(init: EntitiesBuilder.() -> Unit): TextSourcesList = EntitiesBuilder().apply(init).build()
@ -27,13 +26,13 @@ class EntitiesBuilder internal constructor(
*/ */
fun build(): TextSourcesList = entities.toList() fun build(): TextSourcesList = entities.toList()
fun add(source: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) { fun add(source: TextSource) {
entitiesList.add(source) entitiesList.add(source)
} }
operator fun dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource.unaryPlus() = add(this) operator fun TextSource.unaryPlus() = add(this)
operator fun TextSourcesList.unaryPlus() = entitiesList.addAll(this) operator fun TextSourcesList.unaryPlus() = entitiesList.addAll(this)
operator fun invoke(vararg source: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = entitiesList.addAll(source) operator fun invoke(vararg source: TextSource) = entitiesList.addAll(source)
operator fun String.unaryPlus() { operator fun String.unaryPlus() {
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.regular(this)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.regular(this))
@ -42,7 +41,7 @@ class EntitiesBuilder internal constructor(
inline fun EntitiesBuilder.bold(parts: TextSourcesList) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(parts)) inline fun EntitiesBuilder.bold(parts: TextSourcesList) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(parts))
inline fun EntitiesBuilder.bold(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.bold(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(*parts))
inline fun EntitiesBuilder.bold(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(text)) inline fun EntitiesBuilder.bold(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.bold(text))
@ -53,7 +52,7 @@ inline fun EntitiesBuilder.botCommand(command: String) =
inline fun EntitiesBuilder.cashTag(parts: TextSourcesList) = inline fun EntitiesBuilder.cashTag(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(parts))
inline fun EntitiesBuilder.cashTag(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.cashTag(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(*parts))
inline fun EntitiesBuilder.cashTag(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(text)) inline fun EntitiesBuilder.cashTag(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.cashTag(text))
@ -63,7 +62,7 @@ inline fun EntitiesBuilder.code(code: String) = add(dev.inmo.tgbotapi.types.Mess
inline fun EntitiesBuilder.email(parts: TextSourcesList) = inline fun EntitiesBuilder.email(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(parts))
inline fun EntitiesBuilder.email(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.email(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.email(*parts))
inline fun EntitiesBuilder.email(emailAddress: String) = inline fun EntitiesBuilder.email(emailAddress: String) =
@ -72,7 +71,7 @@ inline fun EntitiesBuilder.email(emailAddress: String) =
inline fun EntitiesBuilder.hashtag(parts: TextSourcesList) = inline fun EntitiesBuilder.hashtag(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(parts))
inline fun EntitiesBuilder.hashtag(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.hashtag(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(*parts))
inline fun EntitiesBuilder.hashtag(hashtag: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(hashtag)) inline fun EntitiesBuilder.hashtag(hashtag: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.hashtag(hashtag))
@ -80,7 +79,7 @@ inline fun EntitiesBuilder.hashtag(hashtag: String) = add(dev.inmo.tgbotapi.type
inline fun EntitiesBuilder.italic(parts: TextSourcesList) = inline fun EntitiesBuilder.italic(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(parts))
inline fun EntitiesBuilder.italic(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.italic(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(*parts))
inline fun EntitiesBuilder.italic(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(text)) inline fun EntitiesBuilder.italic(text: String) = add(dev.inmo.tgbotapi.types.MessageEntity.textsources.italic(text))
@ -88,7 +87,7 @@ inline fun EntitiesBuilder.italic(text: String) = add(dev.inmo.tgbotapi.types.Me
inline fun EntitiesBuilder.mention(parts: TextSourcesList) = inline fun EntitiesBuilder.mention(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(parts))
inline fun EntitiesBuilder.mention(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.mention(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(*parts))
inline fun EntitiesBuilder.mention(whoToMention: String) = inline fun EntitiesBuilder.mention(whoToMention: String) =
@ -99,7 +98,7 @@ inline fun EntitiesBuilder.mention(parts: TextSourcesList, user: User) =
inline fun EntitiesBuilder.mention( inline fun EntitiesBuilder.mention(
user: User, user: User,
vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource vararg parts: TextSource
) = ) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(user, *parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.mention(user, *parts))
@ -109,7 +108,7 @@ inline fun EntitiesBuilder.mention(text: String, user: User) =
inline fun EntitiesBuilder.phone(parts: TextSourcesList) = inline fun EntitiesBuilder.phone(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(parts))
inline fun EntitiesBuilder.phone(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.phone(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.phone(*parts))
inline fun EntitiesBuilder.phone(number: String) = inline fun EntitiesBuilder.phone(number: String) =
@ -124,7 +123,7 @@ inline fun EntitiesBuilder.regular(text: String) =
inline fun EntitiesBuilder.strikethrough(parts: TextSourcesList) = inline fun EntitiesBuilder.strikethrough(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(parts))
inline fun EntitiesBuilder.strikethrough(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.strikethrough(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.strikethrough(*parts))
inline fun EntitiesBuilder.strikethrough(text: String) = inline fun EntitiesBuilder.strikethrough(text: String) =
@ -139,7 +138,7 @@ inline fun EntitiesBuilder.link(url: String) =
inline fun EntitiesBuilder.underline(parts: TextSourcesList) = inline fun EntitiesBuilder.underline(parts: TextSourcesList) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(parts))
inline fun EntitiesBuilder.underline(vararg parts: dev.inmo.tgbotapi.types.MessageEntity.textsources.TextSource) = inline fun EntitiesBuilder.underline(vararg parts: TextSource) =
add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(*parts)) add(dev.inmo.tgbotapi.types.MessageEntity.textsources.underline(*parts))
inline fun EntitiesBuilder.underline(text: String) = inline fun EntitiesBuilder.underline(text: String) =