Continue progress on porting OPML code to Swift.
This commit is contained in:
parent
466fd78297
commit
0f8c529d0d
@ -23,11 +23,11 @@ public struct ParsedAuthor: Hashable, Codable, Sendable {
|
||||
}
|
||||
|
||||
/// Use when the actual property is unknown. Guess based on contents of the string. (This is common with RSS.)
|
||||
convenience init(singleString: String) {
|
||||
init(singleString: String) {
|
||||
|
||||
if singleString.contains("@") {
|
||||
init(name: nil, url: nil, avatarURL: nil, emailAddress: singleString)
|
||||
} else if singleString.lowercased.hasPrefix("http") {
|
||||
} else if singleString.lowercased().hasPrefix("http") {
|
||||
init(name: nil, url: singleString, avatarURL: nil, emailAddress: nil)
|
||||
} else {
|
||||
init(name: singleString, url: nil, avatarURL: nil, emailAddress: nil)
|
||||
|
@ -9,12 +9,12 @@ import Foundation
|
||||
|
||||
public struct HTMLTag: Sendable {
|
||||
|
||||
public enum HTMLTagType {
|
||||
public enum TagType {
|
||||
case link
|
||||
case meta
|
||||
}
|
||||
|
||||
public let tagType: HTMLTagType
|
||||
public let tagType: TagType
|
||||
public let attributes: [String: String]?
|
||||
|
||||
public init(tagType: TagType, attributes: [String : String]?) {
|
||||
|
@ -7,10 +7,10 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
final class OPMLDocument: OPMLItem {
|
||||
public final class OPMLDocument: OPMLItem {
|
||||
|
||||
var title: String? = nil
|
||||
var url: String? = nil
|
||||
public var title: String? = nil
|
||||
public var url: String? = nil
|
||||
|
||||
init(url: String?) {
|
||||
self.url = url
|
||||
|
@ -8,9 +8,9 @@
|
||||
import Foundation
|
||||
import os
|
||||
|
||||
class OPMLItem {
|
||||
public class OPMLItem {
|
||||
|
||||
public let feedSpecifier: ParsedOPMLFeedSpecifier
|
||||
public let feedSpecifier: OPMLFeedSpecifier
|
||||
|
||||
public let attributes: [String: String]
|
||||
public let titleFromAttributes: String?
|
||||
|
@ -9,32 +9,63 @@ import Foundation
|
||||
|
||||
public final class OPMLParser {
|
||||
|
||||
let url: String
|
||||
let data: Data
|
||||
private let url: String
|
||||
private let data: Data
|
||||
|
||||
private let opmlDocument: OPMLDocument
|
||||
|
||||
private var itemStack = [OPMLItem]()
|
||||
|
||||
enum OPMLParserError: Error {
|
||||
case notOPML
|
||||
private var currentItem: OPMLItem? {
|
||||
itemStack.last
|
||||
}
|
||||
|
||||
init(parserData: ParserData) {
|
||||
/// Returns nil if data can’t be parsed (if it’s not OPML).
|
||||
public static func document(with parserData: ParserData) -> OPMLDocument? {
|
||||
|
||||
let opmlParser = OPMLParser(parserData)
|
||||
return opmlParser.parse()
|
||||
}
|
||||
|
||||
init(_ parserData: ParserData) {
|
||||
|
||||
self.url = parserData.url
|
||||
self.data = parserData.data
|
||||
self.opmlDocument = OPMLDocument(url: parserData.url)
|
||||
}
|
||||
}
|
||||
|
||||
func parse() throws -> ParsedOPMLDocument {
|
||||
private extension OPMLParser {
|
||||
|
||||
func parse() -> OPMLDocument? {
|
||||
|
||||
guard canParseData() else {
|
||||
throw OPMLParserError.notOPML
|
||||
return nil
|
||||
}
|
||||
|
||||
let parser = SAXParser(delegate: self, data: data)
|
||||
|
||||
pushItem(opmlDocument)
|
||||
|
||||
let saxParser = SAXParser(delegate: self, data: data)
|
||||
saxParser.parse()
|
||||
}
|
||||
|
||||
func canParseData() -> Bool {
|
||||
|
||||
data.containsASCIIString("<opml")
|
||||
}
|
||||
|
||||
func pushItem(_ item: OPMLItem) {
|
||||
|
||||
itemStack.append(item)
|
||||
}
|
||||
|
||||
func popItem() {
|
||||
|
||||
assert(itemStack.count > 0)
|
||||
guard itemStack.count > 0 else {
|
||||
assertionFailure("itemStack.count must be > 0")
|
||||
}
|
||||
|
||||
itemStack.dropLast()
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,12 +82,4 @@ extension OPMLParser: SAXParserDelegate {
|
||||
func saxParser(_: SAXParser, xmlCharactersFound: XMLPointer, count: Int) {
|
||||
|
||||
}
|
||||
|
||||
func saxParser(_: SAXParser, internedStringForName: XMLPointer, prefix: XMLPointer?) -> String? {
|
||||
|
||||
}
|
||||
|
||||
func saxParser(_: SAXParser, internedStringForValue: XMLPointer, count: Int) -> String? {
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user