|
| 1 | +package org.tonstudio.tact.ide.documentation |
| 2 | + |
| 3 | +data class TypeDoc( |
| 4 | + val range: String, |
| 5 | + val size: String, |
| 6 | + val description: String? = null, |
| 7 | + val tlb: String? = null, |
| 8 | +) |
| 9 | + |
| 10 | +val TYPE_DOCS: Map<String, TypeDoc> = mapOf( |
| 11 | + "uint8" to TypeDoc(range = "0 to 255 (2^8 - 1)", size = "8 bits = 1 byte"), |
| 12 | + "uint16" to TypeDoc(range = "0 to 65,535 (2^16 - 1)", size = "16 bits = 2 bytes"), |
| 13 | + "uint32" to TypeDoc(range = "0 to 4,294,967,295 (2^32 - 1)", size = "32 bits = 4 bytes"), |
| 14 | + "uint64" to TypeDoc(range = "0 to 2^64 - 1", size = "64 bits = 8 bytes"), |
| 15 | + "uint128" to TypeDoc(range = "0 to 2^128 - 1", size = "128 bits = 16 bytes"), |
| 16 | + "uint256" to TypeDoc(range = "0 to 2^256 - 1", size = "256 bits = 32 bytes"), |
| 17 | + |
| 18 | + "int8" to TypeDoc(range = "-128 to 127 (-2^7 to 2^7 - 1)", size = "8 bits = 1 byte"), |
| 19 | + "int16" to TypeDoc(range = "-32,768 to 32,767 (-2^15 to 2^15 - 1)", size = "16 bits = 2 bytes"), |
| 20 | + "int32" to TypeDoc(range = "-2^31 to 2^31 - 1", size = "32 bits = 4 bytes"), |
| 21 | + "int64" to TypeDoc(range = "-2^63 to 2^63 - 1", size = "64 bits = 8 bytes"), |
| 22 | + "int128" to TypeDoc(range = "-2^127 to 2^127 - 1", size = "128 bits = 16 bytes"), |
| 23 | + "int256" to TypeDoc(range = "-2^255 to 2^255 - 1", size = "256 bits = 32 bytes"), |
| 24 | + "int257" to TypeDoc(range = "-2^256 to 2^256 - 1", size = "257 bits = 32 bytes + 1 bit"), |
| 25 | + |
| 26 | + "coins" to TypeDoc( |
| 27 | + range = "0 to 2^120 - 1", |
| 28 | + size = "4 to 124 bits", |
| 29 | + description = "An alias to `VarUInteger16`, commonly used for storing `nanoToncoin` amounts. Takes variable bit length depending on the optimal number of bytes needed.", |
| 30 | + tlb = "varuint16" |
| 31 | + ), |
| 32 | + "varuint16" to TypeDoc(range = "0 to 2^120 - 1", size = "4 to 124 bits"), |
| 33 | + "varint16" to TypeDoc(range = "-2^119 to 2^119 - 1", size = "4 to 124 bits"), |
| 34 | + "varuint32" to TypeDoc(range = "0 to 2^248 - 1", size = "5 to 253 bits"), |
| 35 | + "varint32" to TypeDoc(range = "-2^247 to 2^247 - 1", size = "5 to 253 bits") |
| 36 | +) |
| 37 | + |
| 38 | +fun generateArbitraryIntDoc(type: String): TypeDoc? { |
| 39 | + val match = Regex("""^(u?int)(\d+)$""").matchEntire(type) ?: return null |
| 40 | + val (prefix, bitsStr) = match.destructured |
| 41 | + val bitWidth = bitsStr.toInt() |
| 42 | + |
| 43 | + if (prefix == "uint" && (bitWidth < 1 || bitWidth > 256)) return null |
| 44 | + if (prefix == "int" && (bitWidth < 1 || bitWidth > 257)) return null |
| 45 | + |
| 46 | + return if (prefix == "uint") { |
| 47 | + TypeDoc( |
| 48 | + range = "0 to 2^$bitWidth - 1", |
| 49 | + size = "$bitWidth bits", |
| 50 | + description = "Arbitrary bit-width unsigned integer type (available since Tact 1.5)" |
| 51 | + ) |
| 52 | + } else { |
| 53 | + TypeDoc( |
| 54 | + range = "-2^${bitWidth - 1} to 2^${bitWidth - 1} - 1", |
| 55 | + size = "$bitWidth bits", |
| 56 | + description = "Arbitrary bit-width signed integer type (available since Tact 1.5)" |
| 57 | + ) |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +fun generateTlBTypeDoc(word: String): String? { |
| 62 | + if (word == "remaining") { |
| 63 | + return """ |
| 64 | + **remaining** — direct serialization modifier |
| 65 | +
|
| 66 | + - **Applies to**: Cell, Builder, and Slice types |
| 67 | + - **Effect**: Stores/loads data directly in the current cell instead of as a reference |
| 68 | + - **Usage**: `value: Type as remaining` |
| 69 | +
|
| 70 | + Affects how values are serialized into cells. Instead of using references (default), stores data directly in the current cell. |
| 71 | +
|
| 72 | + Learn more in documentation: https://docs.tact-lang.org/book/cells/#serialization-remaining |
| 73 | + """.trimIndent() |
| 74 | + } |
| 75 | + |
| 76 | + val typeInfo = TYPE_DOCS[word] ?: generateArbitraryIntDoc(word) ?: return null |
| 77 | + val isVariable = word.startsWith("var") || word == "coins" |
| 78 | + val isUnsigned = word.startsWith("uint") || word == "coins" |
| 79 | + val bitSizePrefix = if (isVariable) "variable-length" else "${typeInfo.size.split(' ')[0]}-bit" |
| 80 | + |
| 81 | + return buildString { |
| 82 | + appendLine("**$word** — $bitSizePrefix ${if (isUnsigned) "unsigned" else "signed"} integer") |
| 83 | + appendLine() |
| 84 | + appendLine("- **Range**: ${typeInfo.range}") |
| 85 | + appendLine("- **Size**: ${typeInfo.size}") |
| 86 | + append("- **TL-B**: ${typeInfo.tlb ?: word}") |
| 87 | + typeInfo.description?.let { appendLine("\n\n$it") } |
| 88 | + } |
| 89 | +} |
0 commit comments