mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-05 11:18:24 +00:00
fix: clear the remaining compiler warnings in amethyst and desktopApp
Second half of the warning sweep, covering :amethyst (both flavors, all
build types, unit + instrumented tests), :desktopApp and :benchmark:
- GitReplyEvent (NIP-34 kind 1622) is deprecated in favour of NIP-22
comments, but events already on relays still arrive and still have to be
routed, rendered and surfaced. @Suppress("DEPRECATION") with that reason
at the five production sites and the coverage test that pins them.
- The four instrumented Compose tests move to
androidx.compose.ui.test.junit4.v2.createComposeRule. The v2 factory
returns the same ComposeContentTestRule, so mainClock, setContent and the
node assertions are unchanged; only the effect dispatcher differs.
- RelayAuthPromptBusTest / RelayAuthSessionGrantsTest: @OptIn for the
ExperimentalCoroutinesApi members (testScheduler.currentTime, runCurrent)
they already use, matching the annotation the file's other tests carry.
- MarmotFileUploader: drop a nullable alias of a non-null cipher, left
behind when the v2 reference stopped being conditional.
- LocalCacheSearchParityTest: hoist the Json format out of the loader.
- LivesSection: FlowRowOverflow and FlowRow's overflow parameter are
deprecated; the non-deprecated overload already clips beyond maxLines.
- HexBenchmark: drop a bare `null` expression statement from the measured
lambda.
Also fixes :commons:compileCommonMainKotlinMetadata, which did not compile
at all: shared code called BigDecimal.toLong(), which resolves in every
platform compilation (every actual is a Number) but not in the common
metadata one, where only the expect class's own members are visible.
`expect class BigDecimal : Number` cannot work — java.math.BigDecimal leaves
toByte()/toShort() abstract, so the JVM typealias fails the expect/actual
modality check — so the conversion is a top-level expect/actual extension
instead, with actuals next to each BigDecimal actual.
Verified warning- and error-free across the jvm, android (play/fdroid ×
debug/release/benchmark), linuxX64, and the common/jvmAndroid/native/apple/
ios metadata compilations. The apple actuals are checked by
compileAppleMainKotlinMetadata, which runs the frontend against the Apple
klibs without needing a macOS host.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0123kXtseu4X18hL3GMDcdER
This commit is contained in:
+3
-2
@@ -31,7 +31,7 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.test.assertHeightIsAtLeast
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.getUnclippedBoundsInRoot
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.Dp
|
||||
@@ -62,7 +62,8 @@ import org.junit.runner.RunWith
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PlaybackErrorOverlayFitTest {
|
||||
@get:Rule val rule = createComposeRule()
|
||||
@get:Rule
|
||||
val rule = createComposeRule()
|
||||
|
||||
private val targetContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
|
||||
|
||||
+3
-2
@@ -27,7 +27,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.positionInRoot
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.vitorpamplona.amethyst.service.playback.composable.audioSquare
|
||||
@@ -50,7 +50,8 @@ import org.junit.runner.RunWith
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AudioPlayerBoxOverflowTest {
|
||||
@get:Rule val rule = createComposeRule()
|
||||
@get:Rule
|
||||
val rule = createComposeRule()
|
||||
|
||||
private class Bounds {
|
||||
var top = 0f
|
||||
|
||||
+3
-2
@@ -31,7 +31,7 @@ import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalView
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.WindowInsetsAnimationCompat
|
||||
@@ -70,7 +70,8 @@ import org.junit.Test
|
||||
* fallback would silently start reading a dead value too.
|
||||
*/
|
||||
class ComposeImeInsetWedgeTest {
|
||||
@get:Rule val rule = createComposeRule()
|
||||
@get:Rule
|
||||
val rule = createComposeRule()
|
||||
|
||||
private val keyboardHeight = 957
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.vitorpamplona.amethyst.ui.actions.DeferredCrossfade
|
||||
|
||||
+3
@@ -201,6 +201,9 @@ class EventNotificationConsumer(
|
||||
.onFailure { Log.d(TAG) { "Skipping non-decodable npub $npub: ${it.message}" } }
|
||||
.getOrNull()
|
||||
|
||||
// GitReplyEvent (kind 1622) is deprecated in favour of NIP-22 comments, but
|
||||
// events already on relays still arrive and still have to be routed.
|
||||
@Suppress("DEPRECATION")
|
||||
private suspend fun dispatchForAccount(
|
||||
event: Event,
|
||||
account: Account,
|
||||
|
||||
+3
@@ -112,6 +112,9 @@ class NotificationDispatcher(
|
||||
// recipient account.
|
||||
// `internal` (was `private`) so the notification-kinds contract test
|
||||
// can pin the push-side kind set against the in-app feed's kind set.
|
||||
// GitReplyEvent (kind 1622) is deprecated in favour of NIP-22 comments, but
|
||||
// events already on relays still arrive and still have to be routed.
|
||||
@Suppress("DEPRECATION")
|
||||
internal val NOTIFICATION_KINDS: Set<Int> =
|
||||
setOf(
|
||||
// Direct-arrival
|
||||
|
||||
+3
@@ -81,6 +81,9 @@ object CodeNotification {
|
||||
event: GitPullRequestUpdateEvent,
|
||||
) = post(context, account, event.id, event.createdAt, event.pubKey, R.string.app_notification_code_channel_message_pr_update, event.content)
|
||||
|
||||
// GitReplyEvent (kind 1622) is deprecated in favour of NIP-22 comments, but
|
||||
// events already on relays still arrive and still have to be rendered.
|
||||
@Suppress("DEPRECATION")
|
||||
suspend fun notify(
|
||||
context: Context,
|
||||
account: Account,
|
||||
|
||||
+13
-16
@@ -119,7 +119,6 @@ class MarmotFileUploader(
|
||||
// imprecisely.
|
||||
val canonicalMediaType = MarmotMediaType.canonicalize(mimeType) ?: GENERIC_MEDIA_TYPE
|
||||
val cipher = EncryptedMediaV2Cipher(exporterSecret, canonicalMediaType, filename)
|
||||
val v2Cipher = cipher
|
||||
|
||||
item.orchestrator.uploadEncrypted(
|
||||
uri = media.uri,
|
||||
@@ -142,21 +141,19 @@ class MarmotFileUploader(
|
||||
// compression and metadata stripping — because that is what the
|
||||
// key was derived from.
|
||||
val reference =
|
||||
v2Cipher?.let {
|
||||
EncryptedMediaReferenceV2(
|
||||
locators =
|
||||
listOf(
|
||||
MediaLocatorV2(EncryptedMediaPolicyV2.INITIAL_LOCATOR_KIND, serverResult.url),
|
||||
),
|
||||
ciphertextSha256 = it.ciphertextSha256,
|
||||
plaintextSha256 = it.plaintextSha256,
|
||||
nonce = it.nonce,
|
||||
mediaType = it.mediaType,
|
||||
filename = filename,
|
||||
dim = serverResult.fileHeader.dim?.toString(),
|
||||
thumbhash = serverResult.fileHeader.thumbHash?.thumbhash,
|
||||
)
|
||||
}
|
||||
EncryptedMediaReferenceV2(
|
||||
locators =
|
||||
listOf(
|
||||
MediaLocatorV2(EncryptedMediaPolicyV2.INITIAL_LOCATOR_KIND, serverResult.url),
|
||||
),
|
||||
ciphertextSha256 = cipher.ciphertextSha256,
|
||||
plaintextSha256 = cipher.plaintextSha256,
|
||||
nonce = cipher.nonce,
|
||||
mediaType = cipher.mediaType,
|
||||
filename = filename,
|
||||
dim = serverResult.fileHeader.dim?.toString(),
|
||||
thumbhash = serverResult.fileHeader.thumbHash?.thumbhash,
|
||||
)
|
||||
results.add(
|
||||
Mip04UploadResult(
|
||||
url = serverResult.url,
|
||||
|
||||
+6
@@ -139,6 +139,9 @@ class NotificationFeedFilter(
|
||||
AttestationRequestEvent.KIND,
|
||||
)
|
||||
|
||||
// GitReplyEvent (kind 1622) is deprecated in favour of NIP-22 comments, but
|
||||
// events already on relays still arrive and still have to be routed.
|
||||
@Suppress("DEPRECATION")
|
||||
val NOTIFICATION_KINDS =
|
||||
// Kinds that RENDER as a row on the Notifications tab. This is a
|
||||
// display gate over whatever is already in LocalCache — it plays no
|
||||
@@ -268,6 +271,9 @@ class NotificationFeedFilter(
|
||||
|
||||
// Shared with EventNotificationConsumer so push notifications and the
|
||||
// in-app feed apply the same per-kind "is this event for me" rule.
|
||||
// GitReplyEvent (kind 1622) is deprecated in favour of NIP-22 comments, but
|
||||
// events already on relays still arrive and still have to be routed.
|
||||
@Suppress("DEPRECATION")
|
||||
fun tagsAnEventByUser(
|
||||
note: Note,
|
||||
authorHex: HexKey,
|
||||
|
||||
+4
-1
@@ -47,6 +47,9 @@ import java.io.File
|
||||
*/
|
||||
class LocalCacheSearchParityTest {
|
||||
companion object {
|
||||
/** Hoisted out of [loadCorpus]: building a Json format is expensive enough that the compiler warns on it. */
|
||||
private val json = Json { ignoreUnknownKeys = true }
|
||||
|
||||
private lateinit var corpus: List<Event>
|
||||
|
||||
@BeforeClass
|
||||
@@ -57,7 +60,7 @@ class LocalCacheSearchParityTest {
|
||||
.firstOrNull { it.isFile }
|
||||
?: error("tools/search-parity/fixture.json is missing; run tools/search-parity/fetch_fixtures.py")
|
||||
|
||||
val root = Json { ignoreUnknownKeys = true }.parseToJsonElement(file.readText()).jsonObject
|
||||
val root = json.parseToJsonElement(file.readText()).jsonObject
|
||||
corpus =
|
||||
root["cases"]!!
|
||||
.jsonArray
|
||||
|
||||
+1
@@ -153,6 +153,7 @@ class RelayAuthPromptBusTest {
|
||||
* answer already sitting in the deferred, so the relay it belongs to goes unauthenticated for that
|
||||
* long despite the user having answered. Marking it shown is what makes the answer land now.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun anAnswerFannedOutToAQueuedPromptLandsWithoutWaitingOutTheQueueWindow() =
|
||||
runTest {
|
||||
|
||||
+3
@@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.commons.relayauth.RelayAuthPermissionStore
|
||||
import com.vitorpamplona.amethyst.commons.relayauth.RelayAuthPolicy
|
||||
import com.vitorpamplona.amethyst.commons.relayauth.RelayAuthVerdict
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -185,6 +186,7 @@ class RelayAuthSessionGrantsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun promotingAGrantToAlwaysNeverOpensAGapThatRePrompts() =
|
||||
runTest {
|
||||
@@ -205,6 +207,7 @@ class RelayAuthSessionGrantsTest {
|
||||
assertEquals(RelayAuthVerdict.ALLOW, ledger.decide(askable(relay)))
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun neverAllowStopsAuthenticatingBeforeItsWriteLands() =
|
||||
runTest {
|
||||
|
||||
+2
@@ -70,6 +70,7 @@ class Nip34NotificationCoverageTest {
|
||||
* A NIP-22 [com.vitorpamplona.quartz.nip22Comments.CommentEvent] handles
|
||||
* modern comments through its own separate wiring.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
private val nip34ParticipantKinds =
|
||||
setOf(
|
||||
GitPatchEvent.KIND,
|
||||
@@ -131,6 +132,7 @@ class Nip34NotificationCoverageTest {
|
||||
* uppercase `E`. Asserting the wrong half passes the kind list while matching
|
||||
* nothing on the wire.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
@Test
|
||||
fun `status kinds are pulled by the lowercase-e engagement subscription`() {
|
||||
val eAnchoredActivityKinds =
|
||||
|
||||
@@ -136,7 +136,7 @@ class HexBenchmark {
|
||||
/** The pre-existing two-pass way to safely decode an id, for comparison with [hexDecode64OrNull]. */
|
||||
@Test
|
||||
fun hexIsHex64ThenDecode() {
|
||||
r.measureRepeated { if (Hex.isHex64(hex)) Hex.decode(hex) else null }
|
||||
r.measureRepeated { if (Hex.isHex64(hex)) Hex.decode(hex) }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-2
@@ -33,6 +33,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.toLongValue
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -162,7 +163,7 @@ class LiveStreamTopZappersViewModel(
|
||||
when (val ev = note.event) {
|
||||
is LnZapEvent -> {
|
||||
val request = ev.zapRequest ?: return null
|
||||
val sats = ev.amount()?.toLong() ?: return null
|
||||
val sats = ev.amount()?.toLongValue() ?: return null
|
||||
ZapContribution(note.idHex, request.pubKey, request.isAnonTagged(), sats)
|
||||
}
|
||||
is Bolt12ZapEvent -> {
|
||||
@@ -178,7 +179,7 @@ class LiveStreamTopZappersViewModel(
|
||||
): ZapContribution? {
|
||||
val receiptEv = receiptNote?.event as? LnZapEvent ?: return null
|
||||
val request = zapRequestNote.event as? LnZapRequestEvent ?: return null
|
||||
val sats = receiptEv.amount()?.toLong() ?: return null
|
||||
val sats = receiptEv.amount()?.toLongValue() ?: return null
|
||||
return ZapContribution(receiptNote.idHex, request.pubKey, request.isAnonTagged(), sats)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.commons.viewmodels
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.toLongValue
|
||||
|
||||
/**
|
||||
* One in-flight kind-9735 zap to render as a floating overlay on the
|
||||
@@ -59,7 +60,7 @@ data class RoomZap(
|
||||
eventId = event.id,
|
||||
sourcePubkey = event.zapRequest?.pubKey ?: event.pubKey,
|
||||
targetPubkey = event.zappedAuthor().firstOrNull(),
|
||||
amountSats = event.amount?.toLong(),
|
||||
amountSats = event.amount?.toLongValue(),
|
||||
createdAtSec = event.createdAt,
|
||||
)
|
||||
|
||||
|
||||
-2
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.FlowRowOverflow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
@@ -146,7 +145,6 @@ fun LivesSection(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
maxLines = 2,
|
||||
overflow = FlowRowOverflow.Clip,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
) {
|
||||
ranked.forEach { channel ->
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
actual fun BigDecimal.toLongValue(): Long = toLong()
|
||||
+1
-1
@@ -760,7 +760,7 @@ class MarmotInboundProcessor(
|
||||
val author = payloadAuthor(candidate.content.decodeToString())
|
||||
val sender = candidate.senderAccount
|
||||
val valid = author != null && sender != null && author == sender
|
||||
if (valid && sender != null) {
|
||||
if (valid) {
|
||||
convergence.recordWitness(groupId, candidate.stateId, sender)
|
||||
}
|
||||
return GroupEventResult.AppMessageOnCandidateBranch(
|
||||
|
||||
+2
-2
@@ -561,7 +561,7 @@ class MarmotConvergenceEngine(
|
||||
|
||||
return mutex.withLock {
|
||||
val ctx = contexts[groupId] ?: return@withLock null
|
||||
if (rewound && selectedTipId != null) {
|
||||
if (rewound) {
|
||||
adoptBranch(ctx, graph, selectedTipId, inputs.baseId)
|
||||
}
|
||||
// Keep the states of branches that LOST but stay eligible: losing
|
||||
@@ -576,7 +576,7 @@ class MarmotConvergenceEngine(
|
||||
.forEach { tipId ->
|
||||
var cursor: String? = tipId
|
||||
while (cursor != null && cursor !in canonical) {
|
||||
graph.statesById[cursor]?.let { ctx.candidateStates[cursor!!] = it }
|
||||
graph.statesById[cursor]?.let { ctx.candidateStates[cursor] = it }
|
||||
cursor = graph.parentOf[cursor]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,3 +23,15 @@ package com.vitorpamplona.quartz.utils
|
||||
operator fun BigDecimal.plus(other: BigDecimal): BigDecimal = add(other)
|
||||
|
||||
operator fun BigDecimal.minus(other: BigDecimal): BigDecimal = subtract(other)
|
||||
|
||||
/**
|
||||
* Truncate to a Long, the way Number.toLong() does on every platform.
|
||||
*
|
||||
* It has to be an expect *function* rather than a member of `expect class
|
||||
* BigDecimal`: every actual is already a Number and so already has toLong(),
|
||||
* but java.math.BigDecimal leaves toByte()/toShort() abstract, which makes
|
||||
* `expect class BigDecimal : Number` impossible to actualize with the JVM
|
||||
* typealias. Without this, `amount.toLong()` in shared code resolves only in
|
||||
* the platform compilations and breaks `compileCommonMainKotlinMetadata`.
|
||||
*/
|
||||
expect fun BigDecimal.toLongValue(): Long
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
actual fun BigDecimal.toLongValue(): Long = toLong()
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.utils
|
||||
|
||||
actual fun BigDecimal.toLongValue(): Long = toLong()
|
||||
Reference in New Issue
Block a user