nostrdb: add initial swift integration
This commit is contained in:
35
nostrdb/AsciiCharacter.swift
Normal file
35
nostrdb/AsciiCharacter.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// AsciiCharacter.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2023-07-21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct AsciiCharacter: ExpressibleByStringLiteral {
|
||||
private let value: UInt8
|
||||
|
||||
var cchar: CChar {
|
||||
return CChar(bitPattern: value)
|
||||
}
|
||||
|
||||
init?(_ character: Character) {
|
||||
guard let asciiValue = character.asciiValue, asciiValue < 128 else {
|
||||
return nil
|
||||
}
|
||||
self.value = asciiValue
|
||||
}
|
||||
|
||||
// MARK: - ExpressibleByStringLiteral conformance
|
||||
init(stringLiteral value: StringLiteralType) {
|
||||
guard value.count == 1, let character = value.first, let ascii = AsciiCharacter(character) else {
|
||||
fatalError("Invalid ASCII character initialization.")
|
||||
}
|
||||
self = ascii
|
||||
}
|
||||
|
||||
var character: Character {
|
||||
return Character(UnicodeScalar(value))
|
||||
}
|
||||
}
|
||||
42
nostrdb/NdbNote.swift
Normal file
42
nostrdb/NdbNote.swift
Normal file
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// NdbNote.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2023-07-21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct NdbNote {
|
||||
private var owned: Data?
|
||||
let note: UnsafeMutablePointer<ndb_note>
|
||||
|
||||
init(notePointer: UnsafeMutablePointer<ndb_note>, data: Data?) {
|
||||
self.note = notePointer
|
||||
self.owned = data
|
||||
}
|
||||
|
||||
var id: Data {
|
||||
Data(buffer: UnsafeBufferPointer(start: ndb_note_id(note), count: 32))
|
||||
}
|
||||
|
||||
func tags() -> TagsSequence {
|
||||
return .init(note: note)
|
||||
}
|
||||
|
||||
static func owned_from_json(json: String, bufsize: Int = 2 << 18) -> NdbNote? {
|
||||
var data = Data(capacity: bufsize)
|
||||
guard var json_cstr = json.cString(using: .utf8) else { return nil }
|
||||
|
||||
var note: UnsafeMutablePointer<ndb_note>?
|
||||
|
||||
let len = data.withUnsafeMutableBytes { (bytes: UnsafeMutableRawBufferPointer) -> Int in
|
||||
return Int(ndb_note_from_json(&json_cstr, Int32(json_cstr.count), ¬e, bytes.baseAddress, Int32(bufsize)))
|
||||
}
|
||||
|
||||
guard let note else { return nil }
|
||||
|
||||
// Create new Data with just the valid bytes
|
||||
let validData = Data(bytes: ¬e.pointee, count: len)
|
||||
return NdbNote(notePointer: note, data: validData)
|
||||
}}
|
||||
29
nostrdb/NdbTagElem.swift
Normal file
29
nostrdb/NdbTagElem.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// NdbTagElem.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2023-07-21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct NdbTagElem {
|
||||
private let note: UnsafeMutablePointer<ndb_note>
|
||||
private let tag: UnsafeMutablePointer<ndb_tag>
|
||||
let index: Int32
|
||||
|
||||
init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>, index: Int32) {
|
||||
self.note = note
|
||||
self.tag = tag
|
||||
self.index = index
|
||||
}
|
||||
|
||||
func matches_char(c: AsciiCharacter) -> Bool {
|
||||
return ndb_tag_matches_char(note, tag, index, c.cchar) == 1
|
||||
}
|
||||
|
||||
func string() -> String {
|
||||
return String(cString: ndb_tag_str(note, tag, index), encoding: .utf8) ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
47
nostrdb/NdbTagIterator.swift
Normal file
47
nostrdb/NdbTagIterator.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// NdbTagIterators.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2023-07-21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TagSequence: Sequence {
|
||||
let note: UnsafeMutablePointer<ndb_note>
|
||||
let tag: UnsafeMutablePointer<ndb_tag>
|
||||
|
||||
func makeIterator() -> TagIterator {
|
||||
return TagIterator(note: note, tag: tag)
|
||||
}
|
||||
}
|
||||
|
||||
struct TagIterator: IteratorProtocol {
|
||||
typealias Element = NdbTagElem
|
||||
|
||||
mutating func next() -> NdbTagElem? {
|
||||
guard index < tag.pointee.count else { return nil }
|
||||
let el = NdbTagElem(note: note, tag: tag, index: index)
|
||||
|
||||
index += 1
|
||||
|
||||
return el
|
||||
}
|
||||
|
||||
var index: Int32
|
||||
let note: UnsafeMutablePointer<ndb_note>
|
||||
var tag: UnsafeMutablePointer<ndb_tag>
|
||||
|
||||
init(note: UnsafeMutablePointer<ndb_note>, tag: UnsafeMutablePointer<ndb_tag>) {
|
||||
self.note = note
|
||||
self.tag = tag
|
||||
self.index = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func ndb_maybe_pointee<T>(_ p: UnsafeMutablePointer<T>!) -> T? {
|
||||
guard p != nil else { return nil }
|
||||
return p.pointee
|
||||
}
|
||||
|
||||
40
nostrdb/NdbTagsIterator.swift
Normal file
40
nostrdb/NdbTagsIterator.swift
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// NdbTagsIterator.swift
|
||||
// damus
|
||||
//
|
||||
// Created by William Casarin on 2023-07-21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TagsIterator: IteratorProtocol {
|
||||
typealias Element = TagSequence
|
||||
|
||||
var done: Bool
|
||||
var iter: ndb_iterator
|
||||
|
||||
mutating func next() -> TagSequence? {
|
||||
guard !done else { return nil }
|
||||
|
||||
let tag_seq = TagSequence(note: iter.note, tag: self.iter.tag)
|
||||
|
||||
let ok = ndb_tags_iterate_next(&self.iter)
|
||||
done = ok == 0
|
||||
|
||||
return tag_seq
|
||||
}
|
||||
|
||||
init(note: UnsafeMutablePointer<ndb_note>) {
|
||||
self.iter = ndb_iterator()
|
||||
let res = ndb_tags_iterate_start(note, &self.iter)
|
||||
self.done = res == 0
|
||||
}
|
||||
}
|
||||
|
||||
struct TagsSequence: Sequence {
|
||||
let note: UnsafeMutablePointer<ndb_note>
|
||||
|
||||
func makeIterator() -> TagsIterator {
|
||||
return .init(note: note)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user