damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

Id.swift (3462B)


      1 //
      2 //  Id.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2023-07-26.
      6 //
      7 
      8 import Foundation
      9 
     10 struct TagRef<T>: Hashable, Equatable, Encodable {
     11     let elem: TagElem
     12 
     13     init(_ elem: TagElem) {
     14         self.elem = elem
     15     }
     16 
     17     func encode(to encoder: Encoder) throws {
     18         var container = encoder.singleValueContainer()
     19         try container.encode(elem.string())
     20     }
     21 }
     22 
     23 protocol TagKey {
     24     var keychar: AsciiCharacter { get }
     25 }
     26 
     27 protocol TagKeys {
     28     associatedtype TagKeys: TagKey
     29     var key: TagKeys { get }
     30 }
     31 
     32 protocol TagConvertible {
     33     var tag: [String] { get }
     34     static func from_tag(tag: TagSequence) -> Self?
     35 }
     36 
     37 /// Protocol for types that can be converted from/to a tag sequence with the possibilty of an error
     38 protocol ThrowingTagConvertible {
     39     associatedtype E: Error
     40     var tag: [String] { get }
     41     static func fromTag(tag: TagSequence) throws(E) -> Self?
     42 }
     43 
     44 /// Protocol for types that can be converted from/to a tag item
     45 protocol TagItemConvertible {
     46     var tagItem: String? { get }
     47     static func fromTagItem(_ item: String?) -> Self?
     48 }
     49 
     50 struct QuoteId: IdType, TagKey, TagConvertible {
     51     let id: Data
     52     
     53     init(_ data: Data) {
     54         self.id = data
     55     }
     56     
     57     /// The note id being quoted
     58     var note_id: NoteId {
     59         NoteId(self.id)
     60     }
     61 
     62     var keychar: AsciiCharacter { "q" }
     63     
     64     var tag: [String] {
     65         ["q", self.hex()]
     66     }
     67     
     68     static func from_tag(tag: TagSequence) -> QuoteId? {
     69         var i = tag.makeIterator()
     70 
     71         guard tag.count >= 2,
     72               let t0 = i.next(),
     73               let key = t0.single_char,
     74               key == "q",
     75               let t1 = i.next(),
     76               let quote_id = t1.id().map(QuoteId.init)
     77         else { return nil }
     78 
     79         return quote_id
     80     }
     81 }
     82 
     83 
     84 struct Privkey: IdType {
     85     let id: Data
     86 
     87     var nsec: String {
     88         bech32_privkey(self)
     89     }
     90 
     91     init?(hex: String) {
     92         guard let id = hex_decode_id(hex) else {
     93             return nil
     94         }
     95         self.init(id)
     96     }
     97 
     98     init(_ data: Data) {
     99         self.id = data
    100     }
    101 }
    102 
    103 
    104 struct Hashtag: TagConvertible, Hashable {
    105     let hashtag: String
    106 
    107     static func from_tag(tag: TagSequence) -> Hashtag? {
    108         var i = tag.makeIterator()
    109 
    110         guard tag.count >= 2,
    111               let t0 = i.next(),
    112               let chr = t0.single_char,
    113               chr == "t",
    114               let t1 = i.next() else {
    115             return nil
    116         }
    117 
    118         return Hashtag(hashtag: t1.string())
    119     }
    120 
    121     var tag: [String] { ["t", self.hashtag] }
    122     var keychar: AsciiCharacter { "t" }
    123 }
    124 
    125 struct ReplaceableParam: TagConvertible {
    126     let param: TagElem
    127 
    128     static func from_tag(tag: TagSequence) -> ReplaceableParam? {
    129         var i = tag.makeIterator()
    130 
    131         guard tag.count >= 2,
    132               let t0 = i.next(),
    133               let chr = t0.single_char,
    134               chr == "d",
    135               let t1 = i.next() else {
    136             return nil
    137         }
    138 
    139         return ReplaceableParam(param: t1)
    140     }
    141 
    142     var tag: [String] { [self.keychar.description, self.param.string()] }
    143     var keychar: AsciiCharacter { "d" }
    144 }
    145 
    146 struct Signature: Codable, Hashable, Equatable {
    147     let data: Data
    148     
    149     init(from decoder: Decoder) throws {
    150         self.init(try hex_decoder(decoder, expected_len: 64))
    151     }
    152 
    153     func encode(to encoder: Encoder) throws {
    154         try hex_encoder(to: encoder, data: self.data)
    155     }
    156 
    157     init(_ p: Data) {
    158         self.data = p
    159     }
    160 }