- Migrating a mix of tags from the old Tag array methods to the new Tag Object parsers.
- Starting to use fast methods for Tag array loops instead of the native kotlin ones.
This commit is contained in:
@@ -20,17 +20,58 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip01Core.core
|
||||
|
||||
import kotlin.collections.indices
|
||||
|
||||
typealias TagArray = Array<Array<String>>
|
||||
|
||||
fun <T : Event> TagArray.builder(initializer: TagArrayBuilder<T>.() -> Unit = {}) = TagArrayBuilder<T>().addAll(this).apply(initializer).build()
|
||||
|
||||
inline fun <T> Array<out T>.fastForEach(action: (T) -> Unit) {
|
||||
for (index in indices) action(get(index))
|
||||
}
|
||||
|
||||
inline fun <T> Array<out T>.fastAny(predicate: (T) -> Boolean): Boolean {
|
||||
for (index in indices) if (predicate(get(index))) return true
|
||||
return false
|
||||
}
|
||||
|
||||
inline fun <T> Array<out T>.fastFirstOrNull(predicate: (T) -> Boolean): T? {
|
||||
for (index in indices) {
|
||||
if (predicate(get(index))) return get(index)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <T, R : Any> Array<out T>.fastFirstNotNullOfOrNull(transform: (T) -> R?): R? {
|
||||
for (index in indices) {
|
||||
val result = transform(get(index))
|
||||
if (result != null) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <T, U, R : Any> Array<out T>.fastFirstNotNullOfOrNull(
|
||||
transform: (T, U) -> R?,
|
||||
extras: U,
|
||||
): R? {
|
||||
for (index in indices) {
|
||||
val result = transform(get(index), extras)
|
||||
if (result != null) {
|
||||
return result
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each tag that matches the given [tagName].
|
||||
*/
|
||||
fun TagArray.forEachTagged(
|
||||
tagName: String,
|
||||
action: (eventId: HexKey) -> Unit,
|
||||
) = this.forEach {
|
||||
) = this.fastForEach {
|
||||
if (it.size > 1 && it[0] == tagName) {
|
||||
action(it[1])
|
||||
}
|
||||
@@ -42,12 +83,7 @@ fun TagArray.forEachTagged(
|
||||
fun TagArray.anyTagged(
|
||||
tagName: String,
|
||||
predicate: (tagValue: String) -> Boolean,
|
||||
) = this.any { it.size > 1 && it[0] == tagName && predicate(it[1]) }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName].
|
||||
*/
|
||||
fun TagArray.anyTagged(tagName: String) = this.any { it.size > 0 && it[0] == tagName }
|
||||
) = this.fastAny { it.size > 1 && it[0] == tagName && predicate(it[1]) }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName] and its value starts with a prefix
|
||||
@@ -56,12 +92,12 @@ fun TagArray.anyTagWithValueStartingWith(
|
||||
tagName: String,
|
||||
valuePrefix: String,
|
||||
ignoreCase: Boolean = true,
|
||||
): Boolean = this.any { it.size > 1 && it[0] == tagName && it[1].startsWith(valuePrefix, ignoreCase) }
|
||||
): Boolean = this.fastAny { it.size > 1 && it[0] == tagName && it[1].startsWith(valuePrefix, ignoreCase) }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given name and has a value
|
||||
*/
|
||||
fun TagArray.hasTagWithContent(tagName: String) = this.any { it.size > 1 && it[0] == tagName }
|
||||
fun TagArray.hasTagWithContent(tagName: String) = this.fastAny { it.size > 1 && it[0] == tagName }
|
||||
|
||||
/**
|
||||
* Returns a list containing only the non-null results of applying the tag value to the given [transform] function
|
||||
@@ -78,82 +114,20 @@ fun <R> TagArray.mapValueTagged(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing only the non-null results of applying the tag array to the given [transform] function
|
||||
* to each tag that matches the [tagName]
|
||||
*/
|
||||
fun <R> TagArray.mapTagged(
|
||||
tagName: String,
|
||||
map: (tagValue: Array<String>) -> R,
|
||||
) = this.mapNotNull {
|
||||
if (it.size > 1 && it[0] == tagName) {
|
||||
map(it)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list containing only the non-null tag values that match the [tagName]
|
||||
*/
|
||||
fun TagArray.mapValues(tagName: String) =
|
||||
this.mapNotNull {
|
||||
if (it.size > 1 && it[0] == tagName) {
|
||||
it[1]
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first non-null value produced by [transform] function being applied to all tags
|
||||
* that match the [tagName]
|
||||
*/
|
||||
fun <R> TagArray.firstMappedTag(
|
||||
tagName: String,
|
||||
transform: (tagValue: Array<String>) -> R,
|
||||
) = this.firstNotNullOfOrNull {
|
||||
if (it.size > 1 && it[0] == tagName) {
|
||||
transform(it)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of tags that match the given [tagName].
|
||||
*/
|
||||
fun TagArray.filterByTag(tagName: String) = this.filter { it.size > 0 && it[0] == tagName }
|
||||
|
||||
/**
|
||||
* Returns a list of tags that match the given [tagName] and have a tag value.
|
||||
*/
|
||||
fun TagArray.filterByTagWithValue(tagName: String) = this.filter { it.size > 1 && it[0] == tagName }
|
||||
|
||||
/**
|
||||
* Returns the first tag that match the given [tagName] and have a tag value.
|
||||
*/
|
||||
fun TagArray.firstTag(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }
|
||||
|
||||
/**
|
||||
* Returns the first tag value that match the given [tagName] and have a tag value.
|
||||
*/
|
||||
fun TagArray.firstTagValue(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1] }
|
||||
|
||||
/**
|
||||
* Returns the first tag value that match the given [tagName] and have a tag value as integer
|
||||
*/
|
||||
fun TagArray.firstTagValueAsInt(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1].toIntOrNull() }
|
||||
fun TagArray.firstTagValue(key: String) = this.fastFirstOrNull { it.size > 1 && it[0] == key }?.let { it[1] }
|
||||
|
||||
/**
|
||||
* Returns the first tag value that match the given [tagName] and have a tag value as long
|
||||
*/
|
||||
fun TagArray.firstTagValueAsLong(key: String) = this.firstOrNull { it.size > 1 && it[0] == key }?.let { it[1].toLongOrNull() }
|
||||
fun TagArray.firstTagValueAsLong(key: String) = this.fastFirstOrNull { it.size > 1 && it[0] == key }?.let { it[1].toLongOrNull() }
|
||||
|
||||
/**
|
||||
* Returns the first tag value that match any of the given [tagNames] and have a tag value
|
||||
*/
|
||||
fun TagArray.firstTagValueFor(vararg tagNames: String) = this.firstOrNull { it.size > 1 && it[0] in tagNames }?.let { it[1] }
|
||||
fun TagArray.firstTagValueFor(vararg tagNames: String) = this.fastFirstOrNull { it.size > 1 && it[0] in tagNames }?.let { it[1] }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName] and [tagValue]
|
||||
@@ -162,7 +136,7 @@ fun TagArray.isTagged(
|
||||
tagName: String,
|
||||
tagValue: String,
|
||||
ignoreCase: Boolean = false,
|
||||
) = this.any { it.size > 1 && it[0] == tagName && it[1].equals(tagValue, ignoreCase) }
|
||||
) = this.fastAny { it.size > 1 && it[0] == tagName && it[1].equals(tagValue, ignoreCase) }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName] and is in [tagValues]
|
||||
@@ -170,27 +144,16 @@ fun TagArray.isTagged(
|
||||
fun TagArray.isAnyTagged(
|
||||
tagName: String,
|
||||
tagValues: Set<String>,
|
||||
) = this.any { it.size > 1 && it[0] == tagName && it[1] in tagValues }
|
||||
) = this.fastAny { it.size > 1 && it[0] == tagName && it[1] in tagValues }
|
||||
|
||||
fun <U> TagArray.any(
|
||||
predicate: (Array<String>, U) -> Boolean,
|
||||
extras: U,
|
||||
): Boolean {
|
||||
for (element in this) if (predicate(element, extras)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
public inline fun <T, U, R : Any> Array<out T>.firstNotNullOfOrNull(
|
||||
transform: (T, U) -> R?,
|
||||
extras: U,
|
||||
): R? {
|
||||
for (element in this) {
|
||||
val result = transform(element, extras)
|
||||
if (result != null) {
|
||||
return result
|
||||
}
|
||||
for (index in indices) {
|
||||
if (predicate(get(index), extras)) return true
|
||||
}
|
||||
return null
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,7 +162,7 @@ public inline fun <T, U, R : Any> Array<out T>.firstNotNullOfOrNull(
|
||||
fun TagArray.firstAnyLowercaseTaggedValue(
|
||||
tagName: String,
|
||||
tagValues: Set<String>,
|
||||
) = this.firstOrNull { it.size > 1 && it[0] == tagName && it[1].lowercase() in tagValues }?.getOrNull(1)
|
||||
) = this.fastFirstOrNull { it.size > 1 && it[0] == tagName && it[1].lowercase() in tagValues }?.getOrNull(1)
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName] and is in [tagValues]
|
||||
@@ -207,15 +170,7 @@ fun TagArray.firstAnyLowercaseTaggedValue(
|
||||
fun TagArray.isAnyLowercaseTagged(
|
||||
tagName: String,
|
||||
tagValues: Set<String>,
|
||||
) = this.any { it.size > 1 && it[0] == tagName && it[1].lowercase() in tagValues }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag matches the given [tagName] and is in [tagValues]
|
||||
*/
|
||||
fun TagArray.firstAnyTaggedValue(
|
||||
tagName: String,
|
||||
tagValues: Set<String>,
|
||||
) = this.firstOrNull { it.size > 1 && it[0] == tagName && it[1] in tagValues }?.getOrNull(1)
|
||||
) = this.fastAny { it.size > 1 && it[0] == tagName && it[1].lowercase() in tagValues }
|
||||
|
||||
/**
|
||||
* Returns `true` if at least one tag has value that contains [text]
|
||||
@@ -223,12 +178,12 @@ fun TagArray.firstAnyTaggedValue(
|
||||
fun TagArray.tagValueContains(
|
||||
text: String,
|
||||
ignoreCase: Boolean = false,
|
||||
) = this.any { it.size > 1 && it[1].contains(text, ignoreCase) }
|
||||
) = this.fastAny { it.size > 1 && it[1].contains(text, ignoreCase) }
|
||||
|
||||
fun TagArray.containsAllTagNamesWithValues(names: Set<String>): Boolean {
|
||||
val remaining = names.toMutableSet()
|
||||
|
||||
this.forEach {
|
||||
this.fastForEach {
|
||||
if (it.size > 1) {
|
||||
remaining.remove(it[0])
|
||||
}
|
||||
|
||||
+5
-5
@@ -22,12 +22,12 @@ package com.vitorpamplona.quartz.nip01Core.tags.addressables
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.any
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstNotNullOfOrNull
|
||||
import com.vitorpamplona.quartz.nip01Core.core.fastFirstNotNullOfOrNull
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged
|
||||
|
||||
fun <R> TagArray.mapTaggedAddress(map: (address: String) -> R) = this.mapValueTagged(ATag.TAG_NAME, map)
|
||||
|
||||
fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set<String>) = this.firstNotNullOfOrNull(ATag::parseIfIsIn, addressableNotes)
|
||||
fun TagArray.firstIsTaggedAddressableNote(addressableNotes: Set<String>) = this.fastFirstNotNullOfOrNull(ATag::parseIfIsIn, addressableNotes)
|
||||
|
||||
fun TagArray.isTaggedAddressableNote(addressId: String) = this.any(ATag::isTagged, addressId)
|
||||
|
||||
@@ -35,12 +35,12 @@ fun TagArray.isTaggedAddressableNotes(addressIds: Set<String>) = this.any(ATag::
|
||||
|
||||
fun TagArray.isTaggedAddressableKind(kind: Int) = this.any(ATag::isTaggedWithKind, kind.toString())
|
||||
|
||||
fun TagArray.getTagOfAddressableKind(kind: Int) = this.firstNotNullOfOrNull(ATag::parseIfOfKind, kind.toString())
|
||||
fun TagArray.getTagOfAddressableKind(kind: Int) = this.fastFirstNotNullOfOrNull(ATag::parseIfOfKind, kind.toString())
|
||||
|
||||
fun TagArray.taggedATags() = this.mapNotNull(ATag::parse)
|
||||
|
||||
fun TagArray.firstTaggedATag() = this.firstNotNullOfOrNull(ATag::parse)
|
||||
fun TagArray.firstTaggedATag() = this.fastFirstNotNullOfOrNull(ATag::parse)
|
||||
|
||||
fun TagArray.taggedAddresses() = this.mapNotNull(ATag::parseAddress)
|
||||
|
||||
fun TagArray.firstTaggedAddress() = this.firstNotNullOfOrNull(ATag::parseAddress)
|
||||
fun TagArray.firstTaggedAddress() = this.fastFirstNotNullOfOrNull(ATag::parseAddress)
|
||||
|
||||
+17
-2
@@ -21,15 +21,30 @@
|
||||
package com.vitorpamplona.quartz.nip01Core.tags.geohash
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
class GeoHash {
|
||||
class GeoHashTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "g"
|
||||
|
||||
@JvmStatic
|
||||
fun isTagged(tag: Array<String>) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): String? {
|
||||
ensure(tags.has(1)) { return null }
|
||||
ensure(tags[0] == TAG_NAME) { return null }
|
||||
return tags[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assembleSingle(geohash: String) = arrayOf(TAG_NAME, geohash)
|
||||
|
||||
@JvmStatic
|
||||
fun geoMipMap(geohash: String): List<String> = geohash.indices.map { geohash.substring(0, it + 1) }.reversed()
|
||||
|
||||
fun geohashMipMap(geohash: String): TagArray = geoMipMap(geohash).map { arrayOf(TAG_NAME, it) }.toTypedArray()
|
||||
fun geohashMipMap(geohash: String): TagArray = geoMipMap(geohash).map { assembleSingle(it) }.toTypedArray()
|
||||
|
||||
fun assemble(geohash: String) = geohashMipMap(geohash)
|
||||
}
|
||||
+1
-1
@@ -23,4 +23,4 @@ package com.vitorpamplona.quartz.nip01Core.tags.geohash
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
|
||||
fun <T : Event> TagArrayBuilder<T>.geohash(tag: String) = addAll(GeoHash.assemble(tag))
|
||||
fun <T : Event> TagArrayBuilder<T>.geohash(tag: String) = addAll(GeoHashTag.assemble(tag))
|
||||
|
||||
@@ -24,14 +24,13 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.anyTagWithValueStartingWith
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isAnyTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
|
||||
fun TagArray.hasGeohashes() = this.hasTagWithContent(GeoHash.TAG_NAME)
|
||||
fun TagArray.hasGeohashes() = this.hasTagWithContent(GeoHashTag.TAG_NAME)
|
||||
|
||||
fun TagArray.isTaggedGeoHashes(hashtags: Set<String>) = this.isAnyTagged(GeoHash.TAG_NAME, hashtags)
|
||||
fun TagArray.isTaggedGeoHashes(hashtags: Set<String>) = this.isAnyTagged(GeoHashTag.TAG_NAME, hashtags)
|
||||
|
||||
fun TagArray.isTaggedGeoHash(hashtag: String) = this.anyTagWithValueStartingWith(GeoHash.TAG_NAME, hashtag)
|
||||
fun TagArray.isTaggedGeoHash(hashtag: String) = this.anyTagWithValueStartingWith(GeoHashTag.TAG_NAME, hashtag)
|
||||
|
||||
fun TagArray.geohashes() = this.mapValues(GeoHash.TAG_NAME)
|
||||
fun TagArray.geohashes() = this.mapNotNull(GeoHashTag::parse)
|
||||
|
||||
fun TagArray.getGeoHash(): String? = geohashes().maxByOrNull { it.length }?.ifBlank { null }
|
||||
|
||||
+2
-4
@@ -25,18 +25,16 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.anyTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstAnyLowercaseTaggedValue
|
||||
import com.vitorpamplona.quartz.nip01Core.core.forEachTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isAnyLowercaseTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
|
||||
fun TagArray.forEachHashTag(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged(HashtagTag.TAG_NAME, onEach)
|
||||
|
||||
fun TagArray.anyHashTag(onEach: (str: String) -> Boolean) = this.anyTagged(HashtagTag.TAG_NAME, onEach)
|
||||
|
||||
fun TagArray.hasHashtags() = this.hasTagWithContent(HashtagTag.TAG_NAME)
|
||||
fun TagArray.hasHashtags() = this.any(HashtagTag::isTagged)
|
||||
|
||||
fun TagArray.hashtags() = this.mapValues(HashtagTag.TAG_NAME)
|
||||
fun TagArray.hashtags() = this.mapNotNull(HashtagTag::parse)
|
||||
|
||||
fun TagArray.countHashtags() = this.count(HashtagTag::isTagged)
|
||||
|
||||
|
||||
@@ -44,6 +44,13 @@ interface QTag {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Array<String>): String? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseEventAsHint(tag: Array<String>): EventIdHint? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
|
||||
@@ -25,15 +25,14 @@ import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.forEachTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.isTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValueTagged
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
|
||||
fun TagArray.forEachTaggedQuoteId(onEach: (eventId: HexKey) -> Unit) = this.forEachTagged(QTag.TAG_NAME, onEach)
|
||||
|
||||
fun <R> TagArray.mapTaggedQuoteId(map: (eventId: HexKey) -> R) = this.mapValueTagged(QTag.TAG_NAME, map)
|
||||
|
||||
fun TagArray.taggedQuotes() = this.mapNotNull(QTag.Companion::parse)
|
||||
fun TagArray.taggedQuotes() = this.mapNotNull(QTag::parse)
|
||||
|
||||
fun TagArray.taggedQuoteIds() = this.mapValues(QTag.TAG_NAME)
|
||||
fun TagArray.taggedQuoteIds() = this.mapNotNull(QTag::parseKey)
|
||||
|
||||
fun TagArray.firstTaggedQuote() = this.firstNotNullOfOrNull(QTag.Companion::parse)
|
||||
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ package com.vitorpamplona.quartz.nip22Comments.tags
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHashTag
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.ExternalId
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.GeohashId
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
@@ -54,7 +54,7 @@ class ReplyIdentifierTag {
|
||||
@JvmStatic
|
||||
fun assemble(id: ExternalId): List<Array<String>> =
|
||||
when (id) {
|
||||
is GeohashId -> GeoHash.geoMipMap(id.geohash).map { assemble(it, id.hint) }
|
||||
is GeohashId -> GeoHashTag.geoMipMap(id.geohash).map { assemble(it, id.hint) }
|
||||
else -> listOf(assemble(id.toScope(), id.hint()))
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ package com.vitorpamplona.quartz.nip22Comments.tags
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHash
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.geohash.GeoHashTag
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.ExternalId
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.GeohashId
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
@@ -54,7 +54,7 @@ class RootIdentifierTag {
|
||||
@JvmStatic
|
||||
fun assemble(id: ExternalId): List<Array<String>> =
|
||||
when (id) {
|
||||
is GeohashId -> GeoHash.geoMipMap(id.geohash).map { assemble(it, id.hint) }
|
||||
is GeohashId -> GeoHashTag.geoMipMap(id.geohash).map { assemble(it, id.hint) }
|
||||
else -> listOf(assemble(id.toScope(), id.hint()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ data class EmojiUrlTag(
|
||||
}
|
||||
|
||||
fun parse(tag: Array<String>): EmojiUrlTag? =
|
||||
if (tag.size > 2 && tag[0] == "emoji") {
|
||||
if (tag.size > 2 && tag[0] == TAG_NAME) {
|
||||
EmojiUrlTag(tag[1], tag[2])
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -21,6 +21,5 @@
|
||||
package com.vitorpamplona.quartz.nip30CustomEmoji
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapTagged
|
||||
|
||||
fun TagArray.emojis() = this.mapTagged(EmojiUrlTag.TAG_NAME) { EmojiUrlTag.parse(it) }
|
||||
fun TagArray.emojis() = this.mapNotNull(EmojiUrlTag::parse)
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
package com.vitorpamplona.quartz.nip48ProxyTags
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.bytesUsedInMemory
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
|
||||
@Immutable
|
||||
@@ -37,8 +39,12 @@ data class ProxyTag(
|
||||
const val TAG_NAME = "proxy"
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): ProxyTag {
|
||||
require(tags[0] == TAG_NAME)
|
||||
fun isTagged(tag: Array<String>) = tag.has(2) && tag[0] == TAG_NAME && tag[1].isNotEmpty() && tag[2].isNotEmpty()
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): ProxyTag? {
|
||||
ensure(tags.has(2)) { return null }
|
||||
ensure(tags[0] == TAG_NAME) { return null }
|
||||
return ProxyTag(tags[1], tags[2])
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,11 @@
|
||||
package com.vitorpamplona.quartz.nip48ProxyTags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.firstTagValue
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
import com.vitorpamplona.quartz.nip01Core.core.fastAny
|
||||
import com.vitorpamplona.quartz.nip01Core.core.fastFirstNotNullOfOrNull
|
||||
|
||||
fun TagArray.proxies() = this.mapValues(ProxyTag.TAG_NAME)
|
||||
fun TagArray.proxies() = this.mapNotNull(ProxyTag::parse)
|
||||
|
||||
fun TagArray.firstProxy() = this.firstTagValue(ProxyTag.TAG_NAME)
|
||||
fun TagArray.firstProxy() = this.fastFirstNotNullOfOrNull(ProxyTag::parse)
|
||||
|
||||
fun TagArray.hasProxy() = this.hasTagWithContent(ProxyTag.TAG_NAME)
|
||||
fun TagArray.hasProxy() = this.fastAny(ProxyTag::isTagged)
|
||||
|
||||
@@ -26,10 +26,13 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapValues
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag.Companion.parseId
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag.Companion.parseKey
|
||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.pointerSizeInBytes
|
||||
@@ -47,9 +50,9 @@ class LnZapRequestEvent(
|
||||
|
||||
override fun countMemory(): Long = super.countMemory() + pointerSizeInBytes + (privateZapEvent?.countMemory() ?: 0)
|
||||
|
||||
fun zappedPost() = tags.mapValues("e")
|
||||
fun zappedPost() = tags.mapNotNull(ETag::parseId)
|
||||
|
||||
fun zappedAuthor() = tags.mapValues("p")
|
||||
fun zappedAuthor() = tags.mapNotNull(PTag::parseKey)
|
||||
|
||||
fun isPrivateZap() = tags.any { t -> t.size >= 2 && t[0] == "anon" && t[1].isNotBlank() }
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
package com.vitorpamplona.quartz.nip57Zaps.splits
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.hasTagWithContent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.mapTagged
|
||||
|
||||
fun TagArray.hasZapSplitSetup() = this.hasTagWithContent(BaseZapSplitSetup.TAG_NAME)
|
||||
fun TagArray.hasZapSplitSetup() = this.any(ZapSplitSetupParser::isTagged)
|
||||
|
||||
fun TagArray.zapSplitSetup(): List<BaseZapSplitSetup> = this.mapTagged(BaseZapSplitSetup.TAG_NAME) { ZapSplitSetupParser.parse(it) }
|
||||
fun TagArray.zapSplitSetup(): List<BaseZapSplitSetup> = this.mapNotNull(ZapSplitSetupParser::parse)
|
||||
|
||||
+8
-1
@@ -20,11 +20,18 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nip57Zaps.splits
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
class ZapSplitSetupParser {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun isTagged(tags: Array<String>) = tags.has(1) && tags[0] == BaseZapSplitSetup.TAG_NAME
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tags: Array<String>): BaseZapSplitSetup? {
|
||||
require(tags[0] == BaseZapSplitSetup.TAG_NAME)
|
||||
ensure(tags.has(1)) { return null }
|
||||
ensure(tags[0] == BaseZapSplitSetup.TAG_NAME) { return null }
|
||||
|
||||
val isLnAddress = tags[1].contains("@") || tags[1].startsWith("LNURL", true)
|
||||
val weight = if (isLnAddress) 1.0 else (tags.getOrNull(3)?.toDoubleOrNull() ?: 0.0)
|
||||
|
||||
Reference in New Issue
Block a user