2023-07-21 21:54:03 +00:00
|
|
|
//
|
|
|
|
// NdbTagsIterator.swift
|
|
|
|
// damus
|
|
|
|
//
|
|
|
|
// Created by William Casarin on 2023-07-21.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
2023-07-23 17:56:12 +00:00
|
|
|
struct TagsIterator: IteratorProtocol {
|
2023-07-21 21:54:03 +00:00
|
|
|
typealias Element = TagSequence
|
|
|
|
|
|
|
|
var done: Bool
|
|
|
|
var iter: ndb_iterator
|
2023-07-22 23:56:13 +00:00
|
|
|
var note: NdbNote
|
2023-07-21 21:54:03 +00:00
|
|
|
|
|
|
|
mutating func next() -> TagSequence? {
|
2023-07-23 18:55:36 +00:00
|
|
|
guard ndb_tags_iterate_next(&self.iter) == 1 else {
|
|
|
|
done = true
|
|
|
|
return nil
|
|
|
|
}
|
2023-07-21 21:54:03 +00:00
|
|
|
|
2023-07-23 18:55:36 +00:00
|
|
|
return TagSequence(note: note, tag: self.iter.tag)
|
2023-07-21 21:54:03 +00:00
|
|
|
}
|
|
|
|
|
2023-07-23 17:56:12 +00:00
|
|
|
var count: UInt16 {
|
2023-07-23 18:55:36 +00:00
|
|
|
return note.note.pointee.tags.count
|
2023-07-23 17:56:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
init(note: NdbNote) {
|
|
|
|
self.iter = ndb_iterator()
|
2023-07-23 18:55:36 +00:00
|
|
|
ndb_tags_iterate_start(note.note, &self.iter)
|
|
|
|
self.done = false
|
2023-07-23 17:56:12 +00:00
|
|
|
self.note = note
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-26 15:46:44 +00:00
|
|
|
struct TagsSequence: Encodable, Sequence {
|
2023-07-23 17:56:12 +00:00
|
|
|
let note: NdbNote
|
|
|
|
|
|
|
|
var count: UInt16 {
|
|
|
|
note.note.pointee.tags.count
|
|
|
|
}
|
|
|
|
|
2023-07-25 15:58:06 +00:00
|
|
|
func strings() -> [[String]] {
|
|
|
|
return self.map { tag in
|
|
|
|
tag.map { t in t.string() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-26 15:46:44 +00:00
|
|
|
func encode(to encoder: Encoder) throws {
|
|
|
|
var container = encoder.unkeyedContainer()
|
|
|
|
|
|
|
|
// Iterate and create the [[String]] for encoding
|
|
|
|
for tag in self {
|
|
|
|
try container.encode(tag.map { $0.string() })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-23 18:55:36 +00:00
|
|
|
// no O(1) indexing on top-level tag lists unfortunately :(
|
|
|
|
// bit it's very fast to iterate over each tag since the number of tags
|
|
|
|
// are stored and the elements are fixed size.
|
2023-07-26 15:46:44 +00:00
|
|
|
subscript(index: Int) -> Iterator.Element {
|
2023-07-22 23:58:17 +00:00
|
|
|
var i = 0
|
|
|
|
for element in self {
|
|
|
|
if i == index {
|
|
|
|
return element
|
|
|
|
}
|
|
|
|
i += 1
|
|
|
|
}
|
2023-07-26 15:46:44 +00:00
|
|
|
precondition(false, "sequence subscript oob")
|
|
|
|
// it seems like the compiler needs this or it gets bitchy
|
2023-09-10 21:51:55 +00:00
|
|
|
return .init(note: .init(note: .allocate(capacity: 1), owned_size: nil, key: nil), tag: .allocate(capacity: 1))
|
2023-07-24 17:55:34 +00:00
|
|
|
}
|
|
|
|
|
2023-07-23 17:56:12 +00:00
|
|
|
func makeIterator() -> TagsIterator {
|
|
|
|
return .init(note: note)
|
2023-07-21 21:54:03 +00:00
|
|
|
}
|
|
|
|
}
|