diff --git a/Modules/Parser/Sources/Parser/OPML/OPMLAttributes.swift b/Modules/Parser/Sources/Parser/OPML/OPMLAttributes.swift index 0669e0e53..508dd339a 100644 --- a/Modules/Parser/Sources/Parser/OPML/OPMLAttributes.swift +++ b/Modules/Parser/Sources/Parser/OPML/OPMLAttributes.swift @@ -10,13 +10,13 @@ import Foundation // OPML allows for arbitrary attributes. // These are the common attributes in OPML files used as RSS subscription lists. -private static let opmlTextKey = "text" -private static let opmlTitleKey = "title" -private static let opmlDescriptionKey = "description" -private static let opmlTypeKey = "type" -private static let opmlVersionKey = "version" -private static let opmlHMTLURLKey = "htmlUrl" -private static let opmlXMLURLKey = "xmlUrl" +private let opmlTextKey = "text" +private let opmlTitleKey = "title" +private let opmlDescriptionKey = "description" +private let opmlTypeKey = "type" +private let opmlVersionKey = "version" +private let opmlHMTLURLKey = "htmlUrl" +private let opmlXMLURLKey = "xmlUrl" // A frequent error in OPML files is to mess up the capitalization, // so these do a case-insensitive lookup. diff --git a/Modules/Parser/Sources/Parser/OPML/OPMLDocument.swift b/Modules/Parser/Sources/Parser/OPML/OPMLDocument.swift index 647ff215c..55adb982c 100644 --- a/Modules/Parser/Sources/Parser/OPML/OPMLDocument.swift +++ b/Modules/Parser/Sources/Parser/OPML/OPMLDocument.swift @@ -9,6 +9,11 @@ import Foundation final class OPMLDocument: OPMLItem, @unchecked Sendable { - var title: String? - var url: String? + var title: String? = nil + var url: String? = nil + + init(url: String?) { + self.url = url + super.init(attributes: nil) + } } diff --git a/Modules/Parser/Sources/Parser/OPML/OPMLItem.swift b/Modules/Parser/Sources/Parser/OPML/OPMLItem.swift index fba59b526..001ac169a 100644 --- a/Modules/Parser/Sources/Parser/OPML/OPMLItem.swift +++ b/Modules/Parser/Sources/Parser/OPML/OPMLItem.swift @@ -10,7 +10,7 @@ import os class OPMLItem: @unchecked Sendable { - public let feedSpecifier: OPMLFeedSpecifier + public let feedSpecifier: ParsedOPMLFeedSpecifier public let attributes: [String: String] public let titleFromAttributes: String? @@ -20,23 +20,13 @@ class OPMLItem: @unchecked Sendable { items.count > 0 } - init?(attributes: [String : String]) { - - guard let feedURL = attributes.opml_xmlUrl, !feedURL.isEmpty else { - return nil - } - - let titleFromAttributes = { - if let title = attributes.opml_title { - return title - } - return attributes.opml_text - }() - self.titleFromAttributes = titleFromAttributes - - self.feedSpecifier = OPMLFeedSpecifier(title: titleFromAttributes, feedDescription: attributes.opml_description, homePageURL: attributes.opml_htmlUrl, feedURL: feedURL) + init(attributes: [String : String]?) { + self.titleFromAttributes = attributes.opml_title ?? attributes.opml_text self.attributes = attributes + + self.feedSpecifier = ParsedOPMLFeedSpecifier(title: self.titleFromAttributes, feedDescription: attributes.opml_description, homePageURL: attributes.opml_htmlUrl, feedURL: attributes.opml_xmlUrl) + } func addItem(_ item: OPMLItem) { diff --git a/Modules/Parser/Sources/Parser/OPML/OPMLParser.swift b/Modules/Parser/Sources/Parser/OPML/OPMLParser.swift index ad34ff31b..28472fee7 100644 --- a/Modules/Parser/Sources/Parser/OPML/OPMLParser.swift +++ b/Modules/Parser/Sources/Parser/OPML/OPMLParser.swift @@ -12,6 +12,7 @@ public final class OPMLParser { let url: String let data: Data + private let opmlDocument: OPMLDocument private var itemStack = [OPMLItem]() enum OPMLParserError: Error { @@ -22,9 +23,10 @@ public final class OPMLParser { self.url = parserData.url self.data = parserData.data + self.opmlDocument = OPMLDocument(url: parserData.url) } - func parse() throws -> OPMLDocument? { + func parse() throws -> ParsedOPMLDocument { guard canParseData() else { throw OPMLParserError.notOPML