diff --git a/buildSrc/src/main/kotlin/me/alllex/tbot/apigen/BotApiGenerator.kt b/buildSrc/src/main/kotlin/me/alllex/tbot/apigen/BotApiGenerator.kt index 7159a01..549826f 100644 --- a/buildSrc/src/main/kotlin/me/alllex/tbot/apigen/BotApiGenerator.kt +++ b/buildSrc/src/main/kotlin/me/alllex/tbot/apigen/BotApiGenerator.kt @@ -105,55 +105,65 @@ val methodVariations = listOf( data class ValueType( val name: String, val backingType: String, + val docString: String? = null, val fieldPredicate: (type: BotApiElementName, field: BotApiElement.Field) -> Boolean ) val valueTypes = listOf( - ValueType("ChatId", "Long") { type, field -> + ValueType("ChatId", "Long", "Chat identifier.") { type, field -> (type.value == "Chat" && field.serialName == "id") || field.serialName.endsWith("chat_id") }, - ValueType("UserId", "Long") { type, field -> + ValueType("UserId", "Long", "User identifier.") { type, field -> (type.value == "User" && field.serialName == "id") || field.serialName.endsWith("user_id") }, - ValueType("MessageId", "Long") { _, field -> + ValueType("MessageId", "Long", "Opaque message identifier.") { _, field -> !field.serialName.endsWith("inline_message_id") && field.serialName.endsWith("message_id") }, - ValueType("InlineMessageId", "String") { _, field -> + ValueType("InlineMessageId", "String", "Opaque inline message identifier.") { _, field -> field.serialName.endsWith("inline_message_id") }, - ValueType("MessageThreadId", "Long") { _, field -> + ValueType("MessageThreadId", "Long", "Opaque message thread identifier.") { _, field -> field.serialName.endsWith("message_thread_id") }, - ValueType("CallbackQueryId", "String") { type, field -> + ValueType("CallbackQueryId", "String", "Opaque [CallbackQuery] identifier.") { type, field -> (type.value == "CallbackQuery" && field.serialName == "id") || field.serialName.endsWith("callback_query_id") }, - ValueType("InlineQueryId", "String") { type, field -> + ValueType("InlineQueryId", "String", "Opaque [InlineQuery] identifier.") { type, field -> (type.value == "InlineQuery" && field.serialName == "id") || field.serialName.endsWith("inline_query_id") }, - ValueType("InlineQueryResultId", "String") { type, field -> + ValueType("InlineQueryResultId", "String", "Opaque [InlineQueryResult] identifier.") { type, field -> (type.value.startsWith("InlineQuery") && field.serialName == "id") || (type.value == "ChosenInlineResult" && field.serialName == "result_id") }, - ValueType("FileId", "String") { _, field -> + ValueType("FileId", "String", "Identifier for a file, which can be used to download or reuse the file.") { _, field -> field.serialName.endsWith("file_id") }, - ValueType("FileUniqueId", "String") { _, field -> + ValueType( + "FileUniqueId", + "String", + "Unique identifier for a file, which is supposed to be the same over time and for different bots.\n\nIt can't be used to download or reuse the file." + ) { _, field -> field.serialName.endsWith("file_unique_id") }, - ValueType("ShippingQueryId", "String") { type, field -> + ValueType("ShippingQueryId", "String", "Opaque [ShippingQuery] identifier.") { type, field -> (type.value == "ShippingQuery" && field.serialName == "id") || field.serialName.endsWith("shipping_query_id") }, - ValueType("WebAppQueryId", "String") { _, field -> + ValueType("WebAppQueryId", "String", "Opaque web-app query identifier.") { _, field -> field.serialName.endsWith("web_app_query_id") }, - ValueType("CustomEmojiId", "String") { _, field -> + ValueType("CustomEmojiId", "String", "Opaque custom emoji identifier.") { _, field -> field.serialName.endsWith("custom_emoji_id") }, - ValueType("Seconds", "Long") { _, field -> + ValueType("Seconds", "Long", "Duration in seconds.") { _, field -> field.serialName in setOf("cache_time", "duration", "life_period", "open_period", "timeout", "retry_after") }, - ValueType("UnixTimestamp", "Long") { _, field -> + ValueType( + "UnixTimestamp", + "Long", + "Unix time - **number of seconds** that have elapsed since 00:00:00 UTC on 1 January 1970.", + ) { _, field -> field.serialName in setOf( + "date", "last_error_date", "last_synchronization_error_date", "emoji_status_expiration_date", @@ -698,6 +708,13 @@ class BotApiGenerator { } private fun generateValueTypeSourceCode(valueType: ValueType): String = buildString { + valueType.docString?.let { + appendLine("/**") + it.lines().forEach { line -> + appendLine(" * $line") + } + appendLine(" */") + } appendLine("@Serializable") appendLine("@JvmInline") appendLine("value class ${valueType.name}(val value: ${valueType.backingType}) {") diff --git a/src/main/generated-kotlin/me/alllex/tbot/api/model/Types.kt b/src/main/generated-kotlin/me/alllex/tbot/api/model/Types.kt index 3727382..c45c68d 100644 --- a/src/main/generated-kotlin/me/alllex/tbot/api/model/Types.kt +++ b/src/main/generated-kotlin/me/alllex/tbot/api/model/Types.kt @@ -433,7 +433,7 @@ data class Chat( @Serializable data class Message( val messageId: MessageId, - val date: Long, + val date: UnixTimestamp, val chat: Chat, val messageThreadId: MessageThreadId? = null, val from: User? = null, @@ -1546,7 +1546,7 @@ data class ChatMemberBanned( data class ChatMemberUpdated( val chat: Chat, val from: User, - val date: Long, + val date: UnixTimestamp, val oldChatMember: ChatMember, val newChatMember: ChatMember, val inviteLink: ChatInviteLink? = null, @@ -1569,7 +1569,7 @@ data class ChatJoinRequest( val chat: Chat, val from: User, val userChatId: ChatId, - val date: Long, + val date: UnixTimestamp, val bio: String? = null, val inviteLink: ChatInviteLink? = null, ) { @@ -3353,90 +3353,137 @@ object ReplyMarkupSerializer : JsonContentPolymorphicSerializer(Rep } } +/** + * Chat identifier. + */ @Serializable @JvmInline value class ChatId(val value: Long) { override fun toString(): String = "ChatId(${quoteWhenWhitespace(value)})" } +/** + * User identifier. + */ @Serializable @JvmInline value class UserId(val value: Long) { override fun toString(): String = "UserId(${quoteWhenWhitespace(value)})" } +/** + * Opaque message identifier. + */ @Serializable @JvmInline value class MessageId(val value: Long) { override fun toString(): String = "MessageId(${quoteWhenWhitespace(value)})" } +/** + * Opaque inline message identifier. + */ @Serializable @JvmInline value class InlineMessageId(val value: String) { override fun toString(): String = "InlineMessageId(${quoteWhenWhitespace(value)})" } +/** + * Opaque message thread identifier. + */ @Serializable @JvmInline value class MessageThreadId(val value: Long) { override fun toString(): String = "MessageThreadId(${quoteWhenWhitespace(value)})" } +/** + * Opaque [CallbackQuery] identifier. + */ @Serializable @JvmInline value class CallbackQueryId(val value: String) { override fun toString(): String = "CallbackQueryId(${quoteWhenWhitespace(value)})" } +/** + * Opaque [InlineQuery] identifier. + */ @Serializable @JvmInline value class InlineQueryId(val value: String) { override fun toString(): String = "InlineQueryId(${quoteWhenWhitespace(value)})" } +/** + * Opaque [InlineQueryResult] identifier. + */ @Serializable @JvmInline value class InlineQueryResultId(val value: String) { override fun toString(): String = "InlineQueryResultId(${quoteWhenWhitespace(value)})" } +/** + * Identifier for a file, which can be used to download or reuse the file. + */ @Serializable @JvmInline value class FileId(val value: String) { override fun toString(): String = "FileId(${quoteWhenWhitespace(value)})" } +/** + * Unique identifier for a file, which is supposed to be the same over time and for different bots. + * + * It can't be used to download or reuse the file. + */ @Serializable @JvmInline value class FileUniqueId(val value: String) { override fun toString(): String = "FileUniqueId(${quoteWhenWhitespace(value)})" } +/** + * Opaque [ShippingQuery] identifier. + */ @Serializable @JvmInline value class ShippingQueryId(val value: String) { override fun toString(): String = "ShippingQueryId(${quoteWhenWhitespace(value)})" } +/** + * Opaque web-app query identifier. + */ @Serializable @JvmInline value class WebAppQueryId(val value: String) { override fun toString(): String = "WebAppQueryId(${quoteWhenWhitespace(value)})" } +/** + * Opaque custom emoji identifier. + */ @Serializable @JvmInline value class CustomEmojiId(val value: String) { override fun toString(): String = "CustomEmojiId(${quoteWhenWhitespace(value)})" } +/** + * Duration in seconds. + */ @Serializable @JvmInline value class Seconds(val value: Long) { override fun toString(): String = "Seconds(${quoteWhenWhitespace(value)})" } +/** + * Unix time - **number of seconds** that have elapsed since 00:00:00 UTC on 1 January 1970. + */ @Serializable @JvmInline value class UnixTimestamp(val value: Long) { diff --git a/src/main/kotlin/me/alllex/tbot/api/model/Helpers.kt b/src/main/kotlin/me/alllex/tbot/api/model/Helpers.kt index c5b3c7c..6ac97b1 100644 --- a/src/main/kotlin/me/alllex/tbot/api/model/Helpers.kt +++ b/src/main/kotlin/me/alllex/tbot/api/model/Helpers.kt @@ -1,6 +1,7 @@ package me.alllex.tbot.api.model import me.alllex.tbot.api.client.TelegramBotApiClient +import java.time.Instant import kotlin.time.Duration @@ -12,6 +13,8 @@ val Duration.asSeconds get() = Seconds(this.inWholeSeconds) val User.usernameOrId: String get() = "@" + (username ?: id.value.toString()) +fun UnixTimestamp.toInstant(): Instant = Instant.ofEpochMilli(value * 1000) + val MessageEntity.isBotCommand get(): Boolean = type == "bot_command" fun Message.findLeadCommand(): MessageEntity? { diff --git a/version.txt b/version.txt index 9e11b32..10145c2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.3.1 +0.4.0-SNAPSHOT