nostrdb: add initial swift integration

This commit is contained in:
William Casarin
2023-07-21 14:54:03 -07:00
parent dc7826c4e5
commit 61051ee853
7 changed files with 289 additions and 1 deletions

View 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
View 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), &note, bytes.baseAddress, Int32(bufsize)))
}
guard let note else { return nil }
// Create new Data with just the valid bytes
let validData = Data(bytes: &note.pointee, count: len)
return NdbNote(notePointer: note, data: validData)
}}

29
nostrdb/NdbTagElem.swift Normal file
View 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) ?? ""
}
}

View 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
}

View 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)
}
}