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 }