From 32dca9ad2d8a3c263d7e3d08a8301ae8249f7907 Mon Sep 17 00:00:00 2001 From: Nuno Dias Date: Sun, 26 Jan 2025 00:02:45 +0100 Subject: [PATCH] Run swiftformat --- Example/Example/ExampleApp.swift | 35 ++-- Example/Example/Models/FeedItemModel.swift | 45 +++-- Example/Example/Models/FeedModel.swift | 47 ++--- Example/Example/Views/AppleNewsView.swift | 41 ++-- Example/Example/Views/ConcurrencyView.swift | 39 ++-- Example/Example/Views/FeedItemView.swift | 35 ++-- Example/Example/Views/FeedView.swift | 35 ++-- Package.swift | 10 +- Package@swift-5.8.swift | 10 +- Package@swift-5.9.swift | 10 +- .../FeedKit/Extensions/String + toBool.swift | 47 +++-- .../Extensions/String + toDuration.swift | 39 ++-- .../Extensions/String + toGMLPosition.swift | 38 ++-- .../Extensions/String + toKeywords.swift | 35 ++-- .../Extensions/String + toMediaTags.swift | 43 ++-- Sources/FeedKit/Feed.swift | 95 ++++----- Sources/FeedKit/FeedDateFormatter.swift | 96 ++++----- Sources/FeedKit/FeedError.swift | 103 +++++----- Sources/FeedKit/FeedInitializable.swift | 59 +++--- Sources/FeedKit/FeedNamespace.swift | 105 +++++----- Sources/FeedKit/FeedType.swift | 41 ++-- Sources/FeedKit/Feeds/Atom/AtomFeed.swift | 98 +++++----- .../FeedKit/Feeds/Atom/AtomFeedAuthor.swift | 58 +++--- .../FeedKit/Feeds/Atom/AtomFeedCategory.swift | 58 +++--- .../FeedKit/Feeds/Atom/AtomFeedContent.swift | 54 ++--- .../Feeds/Atom/AtomFeedContributor.swift | 58 +++--- .../FeedKit/Feeds/Atom/AtomFeedEntry.swift | 108 +++++----- .../Feeds/Atom/AtomFeedGenerator.swift | 54 ++--- Sources/FeedKit/Feeds/Atom/AtomFeedLink.swift | 70 +++---- .../FeedKit/Feeds/Atom/AtomFeedSource.swift | 58 +++--- .../FeedKit/Feeds/Atom/AtomFeedSubtitle.swift | 47 ++--- .../FeedKit/Feeds/Atom/AtomFeedSummary.swift | 47 ++--- .../FeedKit/Feeds/Atom/AtomFeedTitle.swift | 47 ++--- Sources/FeedKit/Feeds/JSON/JSONFeed.swift | 124 ++++++------ .../Feeds/JSON/JSONFeedAttachment.swift | 66 ++++--- .../FeedKit/Feeds/JSON/JSONFeedAuthor.swift | 58 +++--- Sources/FeedKit/Feeds/JSON/JSONFeedHub.swift | 52 ++--- Sources/FeedKit/Feeds/JSON/JSONFeedItem.swift | 108 +++++----- Sources/FeedKit/Feeds/RSS/RSSFeed.swift | 51 ++--- .../FeedKit/Feeds/RSS/RSSFeedCategory.swift | 45 +++-- .../FeedKit/Feeds/RSS/RSSFeedChannel.swift | 146 +++++++------- Sources/FeedKit/Feeds/RSS/RSSFeedCloud.swift | 66 ++++--- .../FeedKit/Feeds/RSS/RSSFeedEnclosure.swift | 58 +++--- Sources/FeedKit/Feeds/RSS/RSSFeedGUID.swift | 47 ++--- Sources/FeedKit/Feeds/RSS/RSSFeedImage.swift | 70 +++---- Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift | 108 +++++----- .../FeedKit/Feeds/RSS/RSSFeedSkipDay.swift | 39 ++-- .../FeedKit/Feeds/RSS/RSSFeedSkipHours.swift | 35 ++-- Sources/FeedKit/Feeds/RSS/RSSFeedSource.swift | 45 +++-- .../FeedKit/Feeds/RSS/RSSFeedTextInput.swift | 62 +++--- Sources/FeedKit/Namespaces/Atom/Atom.swift | 47 ++--- .../FeedKit/Namespaces/Atom/AtomLink.swift | 70 +++---- .../FeedKit/Namespaces/Content/Content.swift | 48 ++--- .../Namespaces/DublinCore/DublinCore.swift | 106 +++++----- Sources/FeedKit/Namespaces/GML/GMLPoint.swift | 49 ++--- Sources/FeedKit/Namespaces/Geo/GeoRSS.swift | 47 ++--- Sources/FeedKit/Namespaces/Media/Media.swift | 154 ++++++++------- .../Namespaces/Media/MediaBacklinks.swift | 43 ++-- .../Namespaces/Media/MediaCategory.swift | 54 ++--- .../Namespaces/Media/MediaComments.swift | 59 +++--- .../Namespaces/Media/MediaCommunity.swift | 58 +++--- .../Namespaces/Media/MediaContent.swift | 157 ++++++++------- .../Namespaces/Media/MediaCopyright.swift | 47 ++--- .../Namespaces/Media/MediaCredit.swift | 54 ++--- .../Namespaces/Media/MediaDescription.swift | 46 +++-- .../FeedKit/Namespaces/Media/MediaEmbed.swift | 77 ++++---- .../FeedKit/Namespaces/Media/MediaGroup.swift | 62 +++--- .../FeedKit/Namespaces/Media/MediaHash.swift | 45 +++-- .../Namespaces/Media/MediaLicence.swift | 49 ++--- .../Namespaces/Media/MediaLocation.swift | 92 +++++---- .../FeedKit/Namespaces/Media/MediaParam.swift | 43 ++-- .../Namespaces/Media/MediaPeerLink.swift | 49 ++--- .../Namespaces/Media/MediaPlayer.swift | 51 ++--- .../FeedKit/Namespaces/Media/MediaPrice.swift | 62 +++--- .../Namespaces/Media/MediaRating.swift | 45 +++-- .../Namespaces/Media/MediaReponses.swift | 45 +++-- .../Namespaces/Media/MediaRestriction.swift | 54 ++--- .../Namespaces/Media/MediaRights.swift | 47 ++--- .../FeedKit/Namespaces/Media/MediaScene.swift | 62 +++--- .../Namespaces/Media/MediaScenes.swift | 35 ++-- .../Namespaces/Media/MediaStarRating.swift | 62 +++--- .../Namespaces/Media/MediaStatistics.swift | 52 ++--- .../Namespaces/Media/MediaStatus.swift | 54 ++--- .../Namespaces/Media/MediaSubTitle.swift | 58 +++--- .../FeedKit/Namespaces/Media/MediaTag.swift | 52 ++--- .../FeedKit/Namespaces/Media/MediaText.swift | 62 +++--- .../Namespaces/Media/MediaThumbnail.swift | 62 +++--- .../FeedKit/Namespaces/Media/MediaTitle.swift | 45 +++-- .../Namespaces/Syndication/Syndication.swift | 58 +++--- .../Syndication/SyndicationUpdatePeriod.swift | 39 ++-- .../FeedKit/Namespaces/YouTube/Youtube.swift | 71 +++---- .../FeedKit/Namespaces/iTunes/ITunes.swift | 122 ++++++------ .../Namespaces/iTunes/iTunesCategory.swift | 62 +++--- .../Namespaces/iTunes/iTunesImage.swift | 43 ++-- .../Namespaces/iTunes/iTunesOwner.swift | 52 ++--- .../Namespaces/iTunes/iTunesSubCategory.swift | 43 ++-- .../XMLDecoder/XMLDateDecodingStrategy.swift | 35 ++-- Sources/XMLKit/XMLDecoder/XMLDecoder.swift | 99 +++++----- .../XMLKeyedDecodingContainer.swift | 76 +++---- .../XMLSingleValueDecodingContainer.swift | 60 +++--- .../XMLUnkeyedDecodingContainer.swift | 72 +++---- Sources/XMLKit/XMLDocument.swift | 52 ++--- Sources/XMLKit/XMLDocumentConvertible.swift | 35 ++-- Sources/XMLKit/XMLElement.swift | 81 ++++---- Sources/XMLKit/XMLEncoder/XMLCodingKey.swift | 49 ++--- .../XMLEncoder/XMLDateEncodingStrategy.swift | 35 ++-- Sources/XMLKit/XMLEncoder/XMLEncoder.swift | 82 ++++---- .../XMLKeyedEncodingContainer.swift | 68 ++++--- .../XMLSingleValueEncodingContainer.swift | 55 +++--- .../XMLUnkeyedEncodingContainer.swift | 66 ++++--- Sources/XMLKit/XMLError.swift | 65 +++--- Sources/XMLKit/XMLNamespaceCodable.swift | 35 ++-- Sources/XMLKit/XMLNode.swift | 131 +++++++------ Sources/XMLKit/XMLReader.swift | 114 ++++++----- Sources/XMLKit/XMLStack.swift | 51 ++--- Sources/XMLKit/XMLStringConvertible.swift | 35 ++-- Tests/FeedKitTests/FeedKitTestable.swift | 39 ++-- .../Tests/AtomTests + Mocks.swift | 35 ++-- Tests/FeedKitTests/Tests/AtomTests.swift | 36 ++-- Tests/FeedKitTests/Tests/BoolTests.swift | 36 ++-- .../Tests/ContentTests + Mocks.swift | 37 ++-- Tests/FeedKitTests/Tests/ContentTests.swift | 36 ++-- Tests/FeedKitTests/Tests/DateTests.swift | 60 +++--- .../Tests/DublinCoreTests + Mocks.swift | 35 ++-- .../FeedKitTests/Tests/DublinCoreTests.swift | 36 ++-- Tests/FeedKitTests/Tests/DurationTests.swift | 36 ++-- .../Tests/FeedTests + Mocks.swift | 35 ++-- Tests/FeedKitTests/Tests/FeedTests.swift | 36 ++-- Tests/FeedKitTests/Tests/FeedTypeTests.swift | 36 ++-- .../FeedKitTests/Tests/GMLPositionTests.swift | 36 ++-- .../Tests/JSONTests + Mocks.swift | 47 +++-- Tests/FeedKitTests/Tests/JSONTests.swift | 36 ++-- Tests/FeedKitTests/Tests/KeywordsTests.swift | 36 ++-- Tests/FeedKitTests/Tests/MediaTagsTests.swift | 36 ++-- .../Tests/MediaTests + Mocks.swift | 60 +++--- Tests/FeedKitTests/Tests/MediaTests.swift | 36 ++-- .../Tests/RSSAtomTests + Mocks.swift | 35 ++-- Tests/FeedKitTests/Tests/RSSAtomTests.swift | 36 ++-- .../FeedKitTests/Tests/RSSTests + Mocks.swift | 39 ++-- Tests/FeedKitTests/Tests/RSSTests.swift | 36 ++-- .../Tests/SyndicationTests + Mocks.swift | 35 ++-- .../FeedKitTests/Tests/SyndicationTests.swift | 36 ++-- .../Tests/YouTubeTests + Mocks.swift | 37 ++-- Tests/FeedKitTests/Tests/YouTubeTests.swift | 36 ++-- .../Tests/iTunesTests + Mocks.swift | 39 ++-- Tests/FeedKitTests/Tests/iTunesTests.swift | 36 ++-- .../Tests/SampleTests + Mocks.swift | 185 ++++++++++-------- Tests/XMLKitTests/Tests/SampleTests.swift | 50 +++-- Tests/XMLKitTests/XMLKitTestable.swift | 39 ++-- 149 files changed, 4415 insertions(+), 4039 deletions(-) diff --git a/Example/Example/ExampleApp.swift b/Example/Example/ExampleApp.swift index 8b8fef3..7cde9f4 100644 --- a/Example/Example/ExampleApp.swift +++ b/Example/Example/ExampleApp.swift @@ -1,26 +1,25 @@ // -// ExampleApp.swift +// ExampleApp.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import SwiftUI diff --git a/Example/Example/Models/FeedItemModel.swift b/Example/Example/Models/FeedItemModel.swift index ee08a57..5d2fb2e 100644 --- a/Example/Example/Models/FeedItemModel.swift +++ b/Example/Example/Models/FeedItemModel.swift @@ -1,34 +1,31 @@ // -// FeedItemModel.swift +// FeedItemModel.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import Foundation struct FeedItemModel: Equatable { - var title: String? - var description: String? - var date: Date? + // MARK: Lifecycle init() {} @@ -49,4 +46,10 @@ struct FeedItemModel: Equatable { description = item.summary date = item.datePublished } + + // MARK: Internal + + var title: String? + var description: String? + var date: Date? } diff --git a/Example/Example/Models/FeedModel.swift b/Example/Example/Models/FeedModel.swift index 7a88e2c..d097585 100644 --- a/Example/Example/Models/FeedModel.swift +++ b/Example/Example/Models/FeedModel.swift @@ -1,35 +1,31 @@ // -// FeedModel.swift +// FeedModel.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import Foundation struct FeedModel: Equatable { - var title: String? - var date: Date? - var description: String? - var items: [FeedItemModel]? + // MARK: Lifecycle init() {} @@ -63,4 +59,11 @@ struct FeedModel: Equatable { self.init(feed: jsonFeed) } } + + // MARK: Internal + + var title: String? + var date: Date? + var description: String? + var items: [FeedItemModel]? } diff --git a/Example/Example/Views/AppleNewsView.swift b/Example/Example/Views/AppleNewsView.swift index 1d129d1..e49b8e4 100644 --- a/Example/Example/Views/AppleNewsView.swift +++ b/Example/Example/Views/AppleNewsView.swift @@ -1,32 +1,31 @@ // -// AppleNewsView.swift +// AppleNewsView.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import SwiftUI struct AppleNewsView: View { - @State private var feed: RSSFeed = .init() + // MARK: Internal var body: some View { NavigationView { @@ -57,6 +56,10 @@ struct AppleNewsView: View { } } + // MARK: Private + + @State private var feed: RSSFeed = .init() + private func loadFeed() async { do { feed = try await RSSFeed(urlString: "https://developer.apple.com/news/rss/news.rss") diff --git a/Example/Example/Views/ConcurrencyView.swift b/Example/Example/Views/ConcurrencyView.swift index e5adfef..b25d8df 100644 --- a/Example/Example/Views/ConcurrencyView.swift +++ b/Example/Example/Views/ConcurrencyView.swift @@ -1,26 +1,25 @@ // -// ConcurrencyView.swift +// ConcurrencyView.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import SwiftUI @@ -59,7 +58,7 @@ struct ConcurrencyView: View { func loadFeeds() async { feeds = [] await withTaskGroup(of: Result.self) { group in - for urlString in feedUrls { + for urlString in feedURLs { group.addTask { do { let feed = try await Feed(urlString: urlString) @@ -81,7 +80,7 @@ struct ConcurrencyView: View { } } - let feedUrls = [ + let feedURLs = [ "https://www.9to5mac.com/feed/", "https://www.anandtech.com/rss", "https://www.androidauthority.com/feed/", diff --git a/Example/Example/Views/FeedItemView.swift b/Example/Example/Views/FeedItemView.swift index 24ffcb6..26ea41f 100644 --- a/Example/Example/Views/FeedItemView.swift +++ b/Example/Example/Views/FeedItemView.swift @@ -1,26 +1,25 @@ // -// FeedItemView.swift +// FeedItemView.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import SwiftUI diff --git a/Example/Example/Views/FeedView.swift b/Example/Example/Views/FeedView.swift index ccf3b5b..f448482 100644 --- a/Example/Example/Views/FeedView.swift +++ b/Example/Example/Views/FeedView.swift @@ -1,26 +1,25 @@ // -// FeedView.swift +// FeedView.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import FeedKit import SwiftUI diff --git a/Package.swift b/Package.swift index 9bc7d28..ea4b841 100644 --- a/Package.swift +++ b/Package.swift @@ -16,13 +16,13 @@ let package = Package( .library( name: "FeedKit", targets: [ - "FeedKit" + "FeedKit", ] ), .library( name: "XMLKit", targets: [ - "XMLKit" + "XMLKit", ] ), ], @@ -34,19 +34,19 @@ let package = Package( name: "XMLKitTests", dependencies: ["XMLKit"], resources: [ - .process("Resources/xml/Sample.xml") + .process("Resources/xml/Sample.xml"), ] ), .target( name: "FeedKit", dependencies: [ - "XMLKit" + "XMLKit", ] ), .testTarget( name: "FeedKitTests", dependencies: [ - "FeedKit" + "FeedKit", ], resources: [ .process("Resources/json/feed.json"), diff --git a/Package@swift-5.8.swift b/Package@swift-5.8.swift index bcdd6d4..b1f3c1a 100644 --- a/Package@swift-5.8.swift +++ b/Package@swift-5.8.swift @@ -15,13 +15,13 @@ let package = Package( .library( name: "FeedKit", targets: [ - "FeedKit" + "FeedKit", ] ), .library( name: "XMLKit", targets: [ - "XMLKit" + "XMLKit", ] ), ], @@ -33,19 +33,19 @@ let package = Package( name: "XMLKitTests", dependencies: ["XMLKit"], resources: [ - .process("Resources/xml/Sample.xml") + .process("Resources/xml/Sample.xml"), ] ), .target( name: "FeedKit", dependencies: [ - "XMLKit" + "XMLKit", ] ), .testTarget( name: "FeedKitTests", dependencies: [ - "FeedKit" + "FeedKit", ], resources: [ .process("Resources/json/feed.json"), diff --git a/Package@swift-5.9.swift b/Package@swift-5.9.swift index 2061371..a37f6d9 100644 --- a/Package@swift-5.9.swift +++ b/Package@swift-5.9.swift @@ -16,13 +16,13 @@ let package = Package( .library( name: "FeedKit", targets: [ - "FeedKit" + "FeedKit", ] ), .library( name: "XMLKit", targets: [ - "XMLKit" + "XMLKit", ] ), ], @@ -34,19 +34,19 @@ let package = Package( name: "XMLKitTests", dependencies: ["XMLKit"], resources: [ - .process("Resources/xml/Sample.xml") + .process("Resources/xml/Sample.xml"), ] ), .target( name: "FeedKit", dependencies: [ - "XMLKit" + "XMLKit", ] ), .testTarget( name: "FeedKitTests", dependencies: [ - "FeedKit" + "FeedKit", ], resources: [ .process("Resources/json/feed.json"), diff --git a/Sources/FeedKit/Extensions/String + toBool.swift b/Sources/FeedKit/Extensions/String + toBool.swift index f53bd34..e3edc74 100644 --- a/Sources/FeedKit/Extensions/String + toBool.swift +++ b/Sources/FeedKit/Extensions/String + toBool.swift @@ -1,26 +1,25 @@ // -// String + toBool.swift +// String + toBool.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -31,9 +30,15 @@ extension String { /// Returns `nil` for other values. func toBool() -> Bool? { switch lowercased() { - case "true", "y", "yes", "1": return true - case "false", "n", "no", "0": return false - default: return nil + case "1", + "true", + "y", + "yes": true + case "0", + "false", + "n", + "no": false + default: nil } } } diff --git a/Sources/FeedKit/Extensions/String + toDuration.swift b/Sources/FeedKit/Extensions/String + toDuration.swift index a717f6a..d891b25 100644 --- a/Sources/FeedKit/Extensions/String + toDuration.swift +++ b/Sources/FeedKit/Extensions/String + toDuration.swift @@ -1,26 +1,25 @@ // -// String + toDuration.swift +// String + toDuration.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -35,7 +34,9 @@ extension String { guard !comps.contains(where: { Int($0) == nil }), !comps.contains(where: { Int($0)! < 0 }) - else { return nil } + else { + return nil + } return comps .reversed() diff --git a/Sources/FeedKit/Extensions/String + toGMLPosition.swift b/Sources/FeedKit/Extensions/String + toGMLPosition.swift index 0172abd..29a1d2a 100644 --- a/Sources/FeedKit/Extensions/String + toGMLPosition.swift +++ b/Sources/FeedKit/Extensions/String + toGMLPosition.swift @@ -1,26 +1,25 @@ // -// String + toGMLPosition.swift +// String + toGMLPosition.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -42,7 +41,8 @@ extension String { guard let latitude = Double(components[0]), - let longitude = Double(components[1]) else { + let longitude = Double(components[1]) + else { return nil } diff --git a/Sources/FeedKit/Extensions/String + toKeywords.swift b/Sources/FeedKit/Extensions/String + toKeywords.swift index 4fca4bd..fc5b5f8 100644 --- a/Sources/FeedKit/Extensions/String + toKeywords.swift +++ b/Sources/FeedKit/Extensions/String + toKeywords.swift @@ -1,26 +1,25 @@ // -// String + toKeywords.swift +// String + toKeywords.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/FeedKit/Extensions/String + toMediaTags.swift b/Sources/FeedKit/Extensions/String + toMediaTags.swift index 58fb172..eb58492 100644 --- a/Sources/FeedKit/Extensions/String + toMediaTags.swift +++ b/Sources/FeedKit/Extensions/String + toMediaTags.swift @@ -1,26 +1,25 @@ // -// String + toMediaTags.swift +// String + toMediaTags.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -36,13 +35,15 @@ extension String { let components = value.split(separator: ":").map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } - guard !components.isEmpty else { return nil } + guard !components.isEmpty else { + return nil + } - var mediaTag = MediaTag() + var mediaTag: MediaTag = .init() mediaTag.tag = components.first // Default weight if not provided = 1 if components.count > 1 { - mediaTag.weight = Int(components.last ?? "") ?? 1 + mediaTag.weight = Int(components.last ?? "") ?? 1 } else { mediaTag.weight = 1 } diff --git a/Sources/FeedKit/Feed.swift b/Sources/FeedKit/Feed.swift index fffc546..89cd1a3 100644 --- a/Sources/FeedKit/Feed.swift +++ b/Sources/FeedKit/Feed.swift @@ -1,31 +1,30 @@ // -// Feed.swift +// Feed.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation #if canImport(FoundationNetworking) -import FoundationNetworking + import FoundationNetworking #endif /// `Feed` is an enum that can parse and hold either an `AtomFeed`, `RSSFeed`, @@ -38,32 +37,32 @@ import FoundationNetworking /// /// Start by fetching and parsing a feed /// ```swift -///let feed = try await Feed(url: feedURL) -///``` +/// let feed = try await Feed(url: feedURL) +/// ``` /// /// Method 1: Pattern matching with switch /// -///```swift -///switch feed { -///case .atom(let atomFeed): +/// ```swift +/// switch feed { +/// case .atom(let atomFeed): /// print("Atom feed title: \(atomFeed)") -///case .rss(let rssFeed): +/// case .rss(let rssFeed): /// print("RSS feed title: \(rssFeed)") -///case .json(let jsonFeed): +/// case .json(let jsonFeed): /// print("JSON feed title: \(jsonFeed)") -///} -///``` +/// } +/// ``` /// Method 2: Optional property access /// -///```swift +/// ```swift /// -///if let atomFeed = feed.atom { +/// if let atomFeed = feed.atom { /// print("Atom feed: \(atomFeed)") -///} else if let rssFeed = feed.rss { +/// } else if let rssFeed = feed.rss { /// print("RSS feed: \(rssFeed)") -///} else if let jsonFeed = feed.json { +/// } else if let jsonFeed = feed.json { /// print("JSON feed: \(jsonFeed)") -///} +/// } /// ``` /// /// Feed parsing supports both local and remote URLs, raw data, and string input. @@ -85,11 +84,11 @@ extension Feed: FeedInitializable { /// Initializes a `Feed` by parsing content from the specified URL string. /// /// - Parameter urlString: A valid URL string pointing to a feed. - /// - Throws: `FeedError.invalidUrlString` if the URL string is invalid, or other + /// - Throws: `FeedError.invalidURLString` if the URL string is invalid, or other /// parsing errors if the feed content cannot be processed. public init(urlString: String) async throws { guard let url = URL(string: urlString) else { - throw FeedError.invalidUrlString + throw FeedError.invalidURLString } try await self.init(url: url) } @@ -123,7 +122,7 @@ extension Feed: FeedInitializable { /// - Throws: Network errors, HTTP errors, or parsing errors if the download /// fails or the content is invalid. public init(remoteURL url: URL) async throws { - let session = URLSession.shared + let session: URLSession = .shared let (data, response) = try await session.data(from: url) guard let httpResponse = response as? HTTPURLResponse else { @@ -161,14 +160,16 @@ extension Feed: FeedInitializable { /// if parsing fails. public init(data: Data) throws { let feedType = try FeedType(data: data) - + switch feedType { case .atom: let feed = try AtomFeed(data: data) self = .atom(feed) + case .rss: let feed = try RSSFeed(data: data) self = .rss(feed) + case .json: let feed = try JSONFeed(data: data) self = .json(feed) @@ -178,13 +179,15 @@ extension Feed: FeedInitializable { // MARK: - Convenience Accessors -extension Feed { +public extension Feed { /// Returns the wrapped RSS feed if this feed is of type `.rss`. /// /// Use this property to safely access the RSS feed content when you expect /// an RSS format. - public var rss: RSSFeed? { - guard case let .rss(feed) = self else { return nil } + var rss: RSSFeed? { + guard case let .rss(feed) = self else { + return nil + } return feed } @@ -192,8 +195,10 @@ extension Feed { /// /// Use this property to safely access the Atom feed content when you expect /// an Atom format. - public var atom: AtomFeed? { - guard case let .atom(feed) = self else { return nil } + var atom: AtomFeed? { + guard case let .atom(feed) = self else { + return nil + } return feed } @@ -201,8 +206,10 @@ extension Feed { /// /// Use this property to safely access the JSON feed content when you expect /// a JSON format. - public var json: JSONFeed? { - guard case let .json(feed) = self else { return nil } + var json: JSONFeed? { + guard case let .json(feed) = self else { + return nil + } return feed } } diff --git a/Sources/FeedKit/FeedDateFormatter.swift b/Sources/FeedKit/FeedDateFormatter.swift index f756c87..7a41a00 100644 --- a/Sources/FeedKit/FeedDateFormatter.swift +++ b/Sources/FeedKit/FeedDateFormatter.swift @@ -1,40 +1,32 @@ // -// FeedDateFormatter.swift +// FeedDateFormatter.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// PermissiveDateFormatter, used as a base class for date formatting, /// handling multiple date formats and backup formats. class PermissiveDateFormatter: DateFormatter, @unchecked Sendable { - /// Array of date formats to try when converting from string to date. - var dateFormats: [String] { [] } - - /// Array of date formats to try when converting from string to date. - /// Used in permissive parsing strategies when feeds are not fully - /// compliant with the specification and multiple formats need to be - /// attempted to ensure proper date parsing. - var permissiveDateFormats: [String] { [] } + // MARK: Lifecycle /// Initializes the formatter with default timezone and locale. override init() { @@ -44,10 +36,22 @@ class PermissiveDateFormatter: DateFormatter, @unchecked Sendable { } /// Unavailable initializer for decoding. - required init?(coder aDecoder: NSCoder) { + @available(*, unavailable) + required init?(coder _: NSCoder) { fatalError("init(coder:) not supported") } + // MARK: Internal + + /// Array of date formats to try when converting from string to date. + var dateFormats: [String] { [] } + + /// Array of date formats to try when converting from string to date. + /// Used in permissive parsing strategies when feeds are not fully + /// compliant with the specification and multiple formats need to be + /// attempted to ensure proper date parsing. + var permissiveDateFormats: [String] { [] } + /// Attempts to parse a string into a Date using available formats. override func date(from string: String) -> Date? { let trimmedString = string.trimmingCharacters(in: .whitespacesAndNewlines) @@ -198,8 +202,7 @@ enum DateSpec { /// A formatter that handles multiple date specifications (ISO8601, RFC3339, RFC822). class FeedDateFormatter: DateFormatter, @unchecked Sendable { - /// The date specification to use for formatting dates. - let spec: DateSpec + // MARK: Lifecycle /// Initializes the date formatter with a specified date format. /// @@ -209,24 +212,24 @@ class FeedDateFormatter: DateFormatter, @unchecked Sendable { super.init() } - required init?(coder: NSCoder) { + @available(*, unavailable) + required init?(coder _: NSCoder) { fatalError("init(coder:) has not been implemented") } + // MARK: Internal + + /// The date specification to use for formatting dates. + let spec: DateSpec + /// ISO8601 date formatter. - lazy var iso8601Formatter: ISO8601DateFormatter = { - ISO8601DateFormatter() - }() + lazy var iso8601Formatter: ISO8601DateFormatter = .init() /// RFC3339 date formatter. - lazy var rfc3339Formatter: RFC3339DateFormatter = { - RFC3339DateFormatter() - }() + lazy var rfc3339Formatter: RFC3339DateFormatter = .init() /// RFC822 date formatter. - lazy var rfc822Formatter: RFC822DateFormatter = { - RFC822DateFormatter() - }() + lazy var rfc822Formatter: RFC822DateFormatter = .init() /// Converts a string to a Date based on the given date specification. /// @@ -236,14 +239,13 @@ class FeedDateFormatter: DateFormatter, @unchecked Sendable { override func date(from string: String) -> Date? { switch spec { case .iso8601: - return iso8601Formatter.date(from: string) + iso8601Formatter.date(from: string) case .rfc3339: - return rfc3339Formatter.date(from: string) + rfc3339Formatter.date(from: string) case .rfc822: - return rfc822Formatter.date(from: string) + rfc822Formatter.date(from: string) case .permissive: - return - rfc822Formatter.date(from: string) ?? + rfc822Formatter.date(from: string) ?? rfc3339Formatter.date(from: string) ?? iso8601Formatter.date(from: string) } @@ -257,11 +259,11 @@ class FeedDateFormatter: DateFormatter, @unchecked Sendable { override func string(from date: Date) -> String { switch spec { case .iso8601: - return iso8601Formatter.string(from: date) + iso8601Formatter.string(from: date) case .rfc3339: - return rfc3339Formatter.string(from: date) + rfc3339Formatter.string(from: date) case .rfc822: - return rfc822Formatter.string(from: date) + rfc822Formatter.string(from: date) case .permissive: fatalError() } diff --git a/Sources/FeedKit/FeedError.swift b/Sources/FeedKit/FeedError.swift index 3fc372d..29fc94f 100644 --- a/Sources/FeedKit/FeedError.swift +++ b/Sources/FeedKit/FeedError.swift @@ -1,39 +1,38 @@ // -// FeedError.swift +// FeedError.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Error types with `NSError` codes and user info providers. /// -/// - invalidUrlString: The URL string provided is invalid. +/// - invalidURLString: The URL string provided is invalid. /// - invalidHttpResponse: The HTTP response is invalid or has an unexpected /// status code. /// - invalidUtf8String: The provided string cannot be converted to UTF-8 data. /// - unknownFeedFormat: The feed format is not recognized or supported. public enum FeedError: Error { /// The URL string provided is invalid. - case invalidUrlString + case invalidURLString /// The HTTP response is invalid or has an unexpected status code. case invalidHttpResponse(statusCode: Int?) /// The provided string cannot be converted to UTF-8 data. @@ -49,54 +48,62 @@ public enum FeedError: Error { extension FeedError: LocalizedError { public var errorDescription: String? { switch self { - case .invalidUrlString: - return "The URL string provided is invalid." + case .invalidURLString: + "The URL string provided is invalid." + case let .invalidHttpResponse(statusCode): if let code = statusCode { - return "The HTTP response is invalid with status code: \(code)." + "The HTTP response is invalid with status code: \(code)." } else { - return "The HTTP response is invalid with an unknown status code." + "The HTTP response is invalid with an unknown status code." } + case .invalidUtf8String: - return "The provided string cannot be converted to UTF-8 data." + "The provided string cannot be converted to UTF-8 data." + case .unknownFeedFormat: - return "The feed format is not recognized or supported." + "The feed format is not recognized or supported." + case .utf8ConversionFailed: - return "Failed to convert data to a UTF-8 string." + "Failed to convert data to a UTF-8 string." } } public var failureReason: String? { switch self { - case .invalidUrlString: - return "The URL string is not in a valid format." + case .invalidURLString: + "The URL string is not in a valid format." + case let .invalidHttpResponse(statusCode): if let code = statusCode { - return "Received HTTP status code \(code), which is outside the expected range." + "Received HTTP status code \(code), which is outside the expected range." } else { - return "Received an invalid HTTP response with no status code." + "Received an invalid HTTP response with no status code." } + case .invalidUtf8String: - return "The string data is not UTF-8 encoded or contains invalid bytes." + "The string data is not UTF-8 encoded or contains invalid bytes." + case .unknownFeedFormat: - return "The feed format could not be determined from the provided data." + "The feed format could not be determined from the provided data." + case .utf8ConversionFailed: - return "The data could not be represented as a UTF-8 encoded string." + "The data could not be represented as a UTF-8 encoded string." } } public var recoverySuggestion: String? { switch self { - case .invalidUrlString: - return "Verify the URL string and ensure it is correctly formatted." + case .invalidURLString: + "Verify the URL string and ensure it is correctly formatted." case .invalidHttpResponse: - return "Ensure the server is reachable and returning a valid response." + "Ensure the server is reachable and returning a valid response." case .invalidUtf8String: - return "Confirm that the string is UTF-8 encoded and does not contain invalid bytes." + "Confirm that the string is UTF-8 encoded and does not contain invalid bytes." case .unknownFeedFormat: - return "Ensure the feed data is in a recognized RSS, Atom, or JSON format." + "Ensure the feed data is in a recognized RSS, Atom, or JSON format." case .utf8ConversionFailed: - return "Verify that the encoded data can be represented as a string." + "Verify that the encoded data can be represented as a string." } } } @@ -107,17 +114,17 @@ extension FeedError: CustomNSError { /// An error's code for the specified case. public var errorCode: Int { switch self { - case .invalidUrlString: return -1001 - case .invalidHttpResponse: return -1003 - case .invalidUtf8String: return -1004 - case .unknownFeedFormat: return -1005 - case .utf8ConversionFailed: return -1006 + case .invalidURLString: -1001 + case .invalidHttpResponse: -1003 + case .invalidUtf8String: -1004 + case .unknownFeedFormat: -1005 + case .utf8ConversionFailed: -1006 } } /// The error's userInfo dictionary for the specified case. public var errorUserInfo: [String: Any] { - return [ + [ NSLocalizedDescriptionKey: errorDescription ?? "", NSLocalizedFailureReasonErrorKey: failureReason ?? "", NSLocalizedRecoverySuggestionErrorKey: recoverySuggestion ?? "", @@ -126,12 +133,12 @@ extension FeedError: CustomNSError { /// The error's domain for the specified case. public static var errorDomain: String { - return "com.feedkit.error" + "com.feedkit.error" } /// The `NSError` from the specified case. public var error: NSError { - return NSError( + NSError( domain: FeedError.errorDomain, code: errorCode, userInfo: errorUserInfo diff --git a/Sources/FeedKit/FeedInitializable.swift b/Sources/FeedKit/FeedInitializable.swift index dccd6ca..2ab7c17 100644 --- a/Sources/FeedKit/FeedInitializable.swift +++ b/Sources/FeedKit/FeedInitializable.swift @@ -1,30 +1,29 @@ // -// FeedInitializable.swift +// FeedInitializable.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation #if canImport(FoundationNetworking) -import FoundationNetworking + import FoundationNetworking #endif import XMLKit @@ -62,13 +61,13 @@ public protocol FeedInitializable: Codable { // MARK: - Default -extension FeedInitializable { +public extension FeedInitializable { /// Default implementation for initializing from a URL string. /// - Parameter urlString: The URL string of the feed. /// - Throws: An error if the feed cannot be loaded or parsed. - public init(urlString: String) async throws { + init(urlString: String) async throws { guard let url = URL(string: urlString) else { - throw FeedError.invalidUrlString + throw FeedError.invalidURLString } try await self.init(url: url) } @@ -76,7 +75,7 @@ extension FeedInitializable { /// Default implementation for initializing from a URL. /// - Parameter url: The URL of the feed. /// - Throws: An error if the feed cannot be loaded or parsed. - public init(url: URL) async throws { + init(url: URL) async throws { if url.isFileURL { try self.init(fileURL: url) } else { @@ -87,7 +86,7 @@ extension FeedInitializable { /// Initializes from a file URL. /// - Parameter url: The local file URL of the feed. /// - Throws: An error if the file cannot be read or parsed. - public init(fileURL url: URL) throws { + init(fileURL url: URL) throws { let data = try Data(contentsOf: url) try self.init(data: data) } @@ -95,8 +94,8 @@ extension FeedInitializable { /// Initializes from a remote URL. /// - Parameter url: The remote URL of the feed. /// - Throws: An error if fetching or parsing fails. - public init(remoteURL url: URL) async throws { - let session = URLSession.shared + init(remoteURL url: URL) async throws { + let session: URLSession = .shared let (data, response) = try await session.data(from: url) guard let httpResponse = response as? HTTPURLResponse else { @@ -114,7 +113,7 @@ extension FeedInitializable { /// Default implementation for initializing from a string. /// - Parameter string: The feed content as a string. /// - Throws: An error if the string cannot be converted to data or parsed. - public init(string: String) throws { + init(string: String) throws { guard let data = string.data(using: .utf8) else { throw FeedError.invalidUtf8String } @@ -124,7 +123,7 @@ extension FeedInitializable { /// Default implementation for initializing from data. /// - Parameter data: The feed content as raw data. /// - Throws: An error if parsing or decoding fails. - public init(data: Data) throws { + init(data: Data) throws { self = try Self.decode(data: data) } } @@ -136,8 +135,8 @@ extension FeedInitializable { /// - Parameter data: The raw feed data. /// - Returns: A parsed feed model conforming to `FeedInitializable`. private static func decode(data: Data) throws -> Self { - let decoder = XMLDecoder() - let formatter = FeedDateFormatter(spec: .permissive) + let decoder: XMLDecoder = .init() + let formatter: FeedDateFormatter = .init(spec: .permissive) decoder.dateDecodingStrategy = .formatter(formatter) return try decoder.decode(Self.self, from: data) } diff --git a/Sources/FeedKit/FeedNamespace.swift b/Sources/FeedKit/FeedNamespace.swift index 2460060..6d5ac99 100644 --- a/Sources/FeedKit/FeedNamespace.swift +++ b/Sources/FeedKit/FeedNamespace.swift @@ -1,26 +1,25 @@ // -// FeedNamespace.swift +// FeedNamespace.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -59,27 +58,29 @@ enum FeedNamespace: CaseIterable { /// in the Atom format. case atom + // MARK: Internal + /// The namespace prefix. var prefix: String { switch self { case .dublinCore: - return "xmlns:dc" + "xmlns:dc" case .itunes: - return "xmlns:itunes" + "xmlns:itunes" case .syndication: - return "xmlns:sy" + "xmlns:sy" case .media: - return "xmlns:media" + "xmlns:media" case .content: - return "xmlns:content" + "xmlns:content" case .georss: - return "xmlns:georss" + "xmlns:georss" case .gml: - return "xmlns:gml" + "xmlns:gml" case .youTube: - return "xmlns:yt" + "xmlns:yt" case .atom: - return "xmlns:atom" + "xmlns:atom" } } @@ -87,23 +88,23 @@ enum FeedNamespace: CaseIterable { var url: String { switch self { case .dublinCore: - return "http://purl.org/dc/elements/1.1/" + "http://purl.org/dc/elements/1.1/" case .itunes: - return "http://www.itunes.com/dtds/podcast-1.0.dtd" + "http://www.itunes.com/dtds/podcast-1.0.dtd" case .syndication: - return "http://purl.org/rss/1.0/modules/syndication/" + "http://purl.org/rss/1.0/modules/syndication/" case .media: - return "http://search.yahoo.com/mrss/" + "http://search.yahoo.com/mrss/" case .content: - return "http://purl.org/rss/1.0/modules/content/" + "http://purl.org/rss/1.0/modules/content/" case .georss: - return "http://www.georss.org/georss" + "http://www.georss.org/georss" case .gml: - return "http://www.opengis.net/gml" + "http://www.opengis.net/gml" case .youTube: - return "http://www.youtube.com/xml/schemas/2015" + "http://www.youtube.com/xml/schemas/2015" case .atom: - return "http://www.w3.org/2005/Atom" + "http://www.w3.org/2005/Atom" } } } @@ -117,27 +118,33 @@ extension FeedNamespace { func shouldInclude(in feed: RSSFeed) -> Bool { switch self { case .dublinCore: - return - feed.channel?.dublinCore != nil || + feed.channel?.dublinCore != nil || feed.channel?.items?.contains(where: { $0.dublinCore != nil }) ?? false + case .itunes: - return - feed.channel?.iTunes != nil || + feed.channel?.iTunes != nil || feed.channel?.items?.contains(where: { $0.iTunes != nil }) ?? false + case .syndication: - return feed.channel?.syndication != nil + feed.channel?.syndication != nil + case .media: - return feed.channel?.items?.contains(where: { $0.media != nil }) ?? false + feed.channel?.items?.contains(where: { $0.media != nil }) ?? false + case .content: - return feed.channel?.items?.contains(where: { $0.content != nil }) ?? false + feed.channel?.items?.contains(where: { $0.content != nil }) ?? false + case .georss: - return feed.channel?.items?.contains(where: { $0.media?.location?.geoRSS != nil }) ?? false + feed.channel?.items?.contains(where: { $0.media?.location?.geoRSS != nil }) ?? false + case .gml: - return feed.channel?.items?.contains(where: { $0.media?.location?.geoRSS?.gmlPoint != nil }) ?? false + feed.channel?.items?.contains(where: { $0.media?.location?.geoRSS?.gmlPoint != nil }) ?? false + case .youTube: - return false + false + case .atom: - return feed.channel?.atom != nil + feed.channel?.atom != nil } } @@ -147,9 +154,9 @@ extension FeedNamespace { func shouldInclude(in feed: AtomFeed) -> Bool { switch self { case .youTube: - return feed.entries?.contains(where: { $0.youTube != nil }) ?? false + feed.entries?.contains(where: { $0.youTube != nil }) ?? false default: - return false + false } } } diff --git a/Sources/FeedKit/FeedType.swift b/Sources/FeedKit/FeedType.swift index bb4dbf2..f205113 100644 --- a/Sources/FeedKit/FeedType.swift +++ b/Sources/FeedKit/FeedType.swift @@ -1,26 +1,25 @@ // -// FeedType.swift +// FeedType.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -85,7 +84,7 @@ public extension FeedType { } /// The number of bytes to inspect when determining the feed type. -fileprivate let inspectionPrefixLength = 200 +private let inspectionPrefixLength = 200 // MARK: - FeedInitializable @@ -97,7 +96,7 @@ extension FeedType: FeedInitializable { public init(data: Data) throws { // Inspect only the first 200 bytes. This helps improve performance while // still providing enough data to reliably detect the feed format. - let string = String(decoding: data.prefix(inspectionPrefixLength), as: UTF8.self) + let string: String = .init(decoding: data.prefix(inspectionPrefixLength), as: UTF8.self) // Determine the feed type guard let feedType = FeedType.detectFeedType(from: string) else { @@ -126,7 +125,7 @@ public extension FeedType { continue } - let char = Character(scalar) + let char: Character = .init(scalar) switch char { case "<": return detectXMLFeedType(in: string) diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeed.swift b/Sources/FeedKit/Feeds/Atom/AtomFeed.swift index d1bc575..23956d3 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeed.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeed.swift @@ -1,26 +1,25 @@ // -// AtomFeed.swift +// AtomFeed.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -32,6 +31,40 @@ import Foundation /// associated with the feed. Its element children consist of metadata /// elements followed by zero or more atom:entry child elements. public struct AtomFeed { + // MARK: Lifecycle + + public init( + title: AtomFeedTitle? = nil, + subtitle: AtomFeedSubtitle? = nil, + links: [AtomFeedLink]? = nil, + updated: Date? = nil, + categories: [AtomFeedCategory]? = nil, + authors: [AtomFeedAuthor]? = nil, + contributors: [AtomFeedContributor]? = nil, + id: String? = nil, + generator: AtomFeedGenerator? = nil, + icon: String? = nil, + logo: String? = nil, + rights: String? = nil, + entries: [AtomFeedEntry]? = nil + ) { + self.title = title + self.subtitle = subtitle + self.links = links + self.updated = updated + self.categories = categories + self.authors = authors + self.contributors = contributors + self.id = id + self.generator = generator + self.icon = icon + self.logo = logo + self.rights = rights + self.entries = entries + } + + // MARK: Public + /// The "atom:title" element is a Text construct that conveys a human- /// readable title for an entry or feed. public var title: AtomFeedTitle? @@ -160,35 +193,6 @@ public struct AtomFeed { /// appear as the document (i.e., top-level) element of a stand-alone /// Atom Entry Document. public var entries: [AtomFeedEntry]? - - public init( - title: AtomFeedTitle? = nil, - subtitle: AtomFeedSubtitle? = nil, - links: [AtomFeedLink]? = nil, - updated: Date? = nil, - categories: [AtomFeedCategory]? = nil, - authors: [AtomFeedAuthor]? = nil, - contributors: [AtomFeedContributor]? = nil, - id: String? = nil, - generator: AtomFeedGenerator? = nil, - icon: String? = nil, - logo: String? = nil, - rights: String? = nil, - entries: [AtomFeedEntry]? = nil) { - self.title = title - self.subtitle = subtitle - self.links = links - self.updated = updated - self.categories = categories - self.authors = authors - self.contributors = contributors - self.id = id - self.generator = generator - self.icon = icon - self.logo = logo - self.rights = rights - self.entries = entries - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedAuthor.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedAuthor.swift index 574fbe2..64eccc1 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedAuthor.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedAuthor.swift @@ -1,26 +1,25 @@ // -// AtomFeedAuthor.swift +// AtomFeedAuthor.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -34,6 +33,20 @@ import Foundation /// to the entry if there are no atom:author elements in the locations /// described above. public struct AtomFeedAuthor { + // MARK: Lifecycle + + public init( + name: String? = nil, + email: String? = nil, + uri: String? = nil + ) { + self.name = name + self.email = email + self.uri = uri + } + + // MARK: Public + /// The "atom:name" element's content conveys a human-readable name for /// the person. The content of atom:name is Language-Sensitive. Person /// constructs MUST contain exactly one "atom:name" element. @@ -50,15 +63,6 @@ public struct AtomFeedAuthor { /// NOT contain more than one. The content of atom:uri in a Person /// construct MUST be an IRI reference [RFC3987]. public var uri: String? - - public init( - name: String? = nil, - email: String? = nil, - uri: String? = nil) { - self.name = name - self.email = email - self.uri = uri - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedCategory.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedCategory.swift index 6e76ece..7cdee88 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedCategory.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedCategory.swift @@ -1,31 +1,44 @@ // -// AtomFeedCategory.swift +// AtomFeedCategory.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedCategoryAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + term: String? = nil, + scheme: String? = nil, + label: String? = nil + ) { + self.term = term + self.scheme = scheme + self.label = label + } + + // MARK: Public + /// The "term" attribute is a string that identifies the category to /// which the entry or feed belongs. Category elements MUST have a /// "term" attribute. @@ -41,15 +54,6 @@ public struct AtomFeedCategoryAttributes: Codable, Equatable, Hashable, Sendable /// their corresponding characters ("&" and "<", respectively), not /// markup. Category elements MAY have a "label" attribute. public var label: String? - - public init( - term: String? = nil, - scheme: String? = nil, - label: String? = nil) { - self.term = term - self.scheme = scheme - self.label = label - } } /// The "atom:category" element conveys information about a category diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedContent.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedContent.swift index 2f214bc..4b34adf 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedContent.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedContent.swift @@ -1,31 +1,42 @@ // -// AtomFeedContent.swift +// AtomFeedContent.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedContentAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + type: String? = nil, + src: String? = nil + ) { + self.type = type + self.src = src + } + + // MARK: Public + /// On the atom:content element, the value of the "type" attribute MAY be /// one of "text", "html", or "xhtml". Failing that, it MUST conform to /// the syntax of a MIME media type, but MUST NOT be a composite type @@ -47,13 +58,6 @@ public struct AtomFeedContentAttributes: Codable, Equatable, Hashable, Sendable /// if the server providing that content also provides a media type, the /// server-provided media type is authoritative. public var src: String? - - public init( - type: String? = nil, - src: String? = nil) { - self.type = type - self.src = src - } } /// The "atom:content" element either contains or links to the content of diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedContributor.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedContributor.swift index b29a821..050908f 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedContributor.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedContributor.swift @@ -1,32 +1,45 @@ // -// AtomFeedContributor.swift +// AtomFeedContributor.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// The "atom:contributor" element is a Person construct that indicates a /// person or other entity who contributed to the entry or feed. public struct AtomFeedContributor { + // MARK: Lifecycle + + public init( + name: String? = nil, + email: String? = nil, + uri: String? = nil + ) { + self.name = name + self.email = email + self.uri = uri + } + + // MARK: Public + /// The "atom:name" element's content conveys a human-readable name for /// the person. The content of atom:name is Language-Sensitive. Person /// constructs MUST contain exactly one "atom:name" element. @@ -43,15 +56,6 @@ public struct AtomFeedContributor { /// NOT contain more than one. The content of atom:uri in a Person /// construct MUST be an IRI reference [RFC3987]. public var uri: String? - - public init( - name: String? = nil, - email: String? = nil, - uri: String? = nil) { - self.name = name - self.email = email - self.uri = uri - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedEntry.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedEntry.swift index 2c9547e..b689b9b 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedEntry.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedEntry.swift @@ -1,26 +1,25 @@ // -// AtomFeedEntry.swift +// AtomFeedEntry.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -30,6 +29,42 @@ import Foundation /// appear as the document (i.e., top-level) element of a stand-alone /// Atom Entry Document. public struct AtomFeedEntry { + // MARK: Lifecycle + + public init( + title: String? = nil, + summary: AtomFeedSummary? = nil, + authors: [AtomFeedAuthor]? = nil, + contributors: [AtomFeedContributor]? = nil, + links: [AtomFeedLink]? = nil, + updated: Date? = nil, + categories: [AtomFeedCategory]? = nil, + id: String? = nil, + content: AtomFeedContent? = nil, + published: Date? = nil, + source: AtomFeedSource? = nil, + rights: String? = nil, + media: Media? = nil, + youTube: YouTube? = nil + ) { + self.title = title + self.summary = summary + self.authors = authors + self.contributors = contributors + self.links = links + self.updated = updated + self.categories = categories + self.id = id + self.content = content + self.published = published + self.source = source + self.rights = rights + self.media = media + self.youTube = youTube + } + + // MARK: Public + /// The "atom:title" element is a Text construct that conveys a human- /// readable title for an entry or feed. public var title: String? @@ -158,46 +193,15 @@ public struct AtomFeedEntry { /// then the atom:rights element of the containing atom:feed element, if /// present, is considered to apply to the entry. public var rights: String? - + /// Media RSS is a new RSS module that supplements the /// capabilities of RSS 2.0. public var media: Media? - + /// YouTube metadata contains channel ID and video ID for YouTube content. /// /// See https://developers.google.com/youtube/v3/guides/push_notifications public var youTube: YouTube? - - public init( - title: String? = nil, - summary: AtomFeedSummary? = nil, - authors: [AtomFeedAuthor]? = nil, - contributors: [AtomFeedContributor]? = nil, - links: [AtomFeedLink]? = nil, - updated: Date? = nil, - categories: [AtomFeedCategory]? = nil, - id: String? = nil, - content: AtomFeedContent? = nil, - published: Date? = nil, - source: AtomFeedSource? = nil, - rights: String? = nil, - media: Media? = nil, - youTube: YouTube? = nil) { - self.title = title - self.summary = summary - self.authors = authors - self.contributors = contributors - self.links = links - self.updated = updated - self.categories = categories - self.id = id - self.content = content - self.published = published - self.source = source - self.rights = rights - self.media = media - self.youTube = youTube - } } // MARK: - Sendable @@ -228,7 +232,7 @@ extension AtomFeedEntry: Codable { case published case source case rights - case media = "media" + case media case youTube = "yt" } diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedGenerator.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedGenerator.swift index de57172..3074087 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedGenerator.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedGenerator.swift @@ -1,31 +1,42 @@ // -// AtomFeedGenerator.swift +// AtomFeedGenerator.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedGeneratorAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + uri: String? = nil, + version: String? = nil + ) { + self.uri = uri + self.version = version + } + + // MARK: Public + /// The atom:generator element MAY have a "uri" attribute whose value /// MUST be an IRI reference [RFC3987]. When dereferenced, the resulting /// URI (mapped from an IRI, if necessary) SHOULD produce a @@ -35,13 +46,6 @@ public struct AtomFeedGeneratorAttributes: Codable, Equatable, Hashable, Sendabl /// The atom:generator element MAY have a "version" attribute that /// indicates the version of the generating agent. public var version: String? - - public init( - uri: String? = nil, - version: String? = nil) { - self.uri = uri - self.version = version - } } /// The "atom:generator" element's content identifies the agent used to diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedLink.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedLink.swift index cca69cf..b204220 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedLink.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedLink.swift @@ -1,31 +1,50 @@ // -// AtomFeedLink.swift +// AtomFeedLink.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedLinkAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + href: String? = nil, + rel: String? = nil, + type: String? = nil, + hreflang: String? = nil, + title: String? = nil, + length: Int64? = nil + ) { + self.href = href + self.rel = rel + self.type = type + self.hreflang = hreflang + self.title = title + self.length = length + } + + // MARK: Public + /// The "href" attribute contains the link's IRI. atom:link elements MUST /// have an href attribute, whose value MUST be a IRI reference /// [RFC3987]. @@ -112,21 +131,6 @@ public struct AtomFeedLinkAttributes: Codable, Equatable, Hashable, Sendable { /// by the underlying protocol. Link elements MAY have a length /// attribute. public var length: Int64? - - public init( - href: String? = nil, - rel: String? = nil, - type: String? = nil, - hreflang: String? = nil, - title: String? = nil, - length: Int64? = nil) { - self.href = href - self.rel = rel - self.type = type - self.hreflang = hreflang - self.title = title - self.length = length - } } /// The "atom:link" element defines a reference from an entry or feed to diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift index bbeb38e..ac7ee73 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedSource.swift @@ -1,26 +1,25 @@ // -// AtomFeedSource.swift +// AtomFeedSource.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -42,6 +41,20 @@ import Foundation /// feed-level Metadata elements (atom:id, atom:title, and atom:updated) /// in the atom:source element. public struct AtomFeedSource { + // MARK: Lifecycle + + public init( + id: String? = nil, + title: String? = nil, + updated: Date? = nil + ) { + self.id = id + self.title = title + self.updated = updated + } + + // MARK: Public + /// The "atom:id" element conveys a permanent, universally unique /// identifier for an entry or feed. public var id: String? @@ -55,15 +68,6 @@ public struct AtomFeedSource { /// the publisher considers significant. Therefore, not all /// modifications necessarily result in a changed atom:updated value. public var updated: Date? - - public init( - id: String? = nil, - title: String? = nil, - updated: Date? = nil) { - self.id = id - self.title = title - self.updated = updated - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedSubtitle.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedSubtitle.swift index 601ebe3..0c6a002 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedSubtitle.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedSubtitle.swift @@ -1,40 +1,43 @@ // -// AtomFeedSubtitle.swift +// AtomFeedSubtitle.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedSubtitleAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(type: String? = nil) { + self.type = type + } + + // MARK: Public + /// Text constructs MAY have a "type" attribute. When present, the value /// MUST be one of "text", "html", or "xhtml". If the "type" attribute /// is not provided, Atom Processors MUST behave as though it were /// present with a value of "text". public var type: String? - - public init(type: String? = nil) { - self.type = type - } } /// The "atom:subtitle" element is a Text construct that conveys a human- diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedSummary.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedSummary.swift index 01a4d37..4e4410f 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedSummary.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedSummary.swift @@ -1,40 +1,43 @@ // -// AtomFeedSummary.swift +// AtomFeedSummary.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedSummaryAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(type: String? = nil) { + self.type = type + } + + // MARK: Public + /// Text constructs MAY have a "type" attribute. When present, the value /// MUST be one of "text", "html", or "xhtml". If the "type" attribute /// is not provided, Atom Processors MUST behave as though it were /// present with a value of "text". public var type: String? - - public init(type: String? = nil) { - self.type = type - } } /// The "atom:summary" element is a Text construct that conveys a short diff --git a/Sources/FeedKit/Feeds/Atom/AtomFeedTitle.swift b/Sources/FeedKit/Feeds/Atom/AtomFeedTitle.swift index 1c0c6e5..505c022 100644 --- a/Sources/FeedKit/Feeds/Atom/AtomFeedTitle.swift +++ b/Sources/FeedKit/Feeds/Atom/AtomFeedTitle.swift @@ -1,40 +1,43 @@ // -// AtomFeedTitle.swift +// AtomFeedTitle.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomFeedTitleAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(type: String? = nil) { + self.type = type + } + + // MARK: Public + /// Text constructs MAY have a "type" attribute. When present, the value /// MUST be one of "text", "html", or "xhtml". If the "type" attribute /// is not provided, Atom Processors MUST behave as though it were /// present with a value of "text". public var type: String? - - public init(type: String? = nil) { - self.type = type - } } /// The "atom:title" element is a Text construct that conveys a human- diff --git a/Sources/FeedKit/Feeds/JSON/JSONFeed.swift b/Sources/FeedKit/Feeds/JSON/JSONFeed.swift index 3d70d9c..bf783f1 100644 --- a/Sources/FeedKit/Feeds/JSON/JSONFeed.swift +++ b/Sources/FeedKit/Feeds/JSON/JSONFeed.swift @@ -1,26 +1,25 @@ // -// JSONFeed.swift +// JSONFeed.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,10 +27,37 @@ import Foundation /// but with one big difference: it's JSON instead of XML. /// See https://jsonfeed.org/version/1 public struct JSONFeed { - /// (required, string) is the URL of the version of the format the feed - /// uses. This should appear at the very top, though we recognize that not all - /// JSON generators allow for ordering. - var version: String = "https://jsonfeed.org/version/1" + // MARK: Lifecycle + + public init( + title: String? = nil, + homePageURL: String? = nil, + feedURL: String? = nil, + description: String? = nil, + userComment: String? = nil, + nextURL: String? = nil, + icon: String? = nil, + favicon: String? = nil, + author: JSONFeedAuthor? = nil, + expired: Bool? = nil, + hubs: [JSONFeedHub]? = nil, + items: [JSONFeedItem]? = nil + ) { + self.title = title + self.homePageURL = homePageURL + self.feedURL = feedURL + self.description = description + self.userComment = userComment + self.nextURL = nextURL + self.icon = icon + self.favicon = favicon + self.author = author + self.expired = expired + self.hubs = hubs + self.items = items + } + + // MARK: Public /// (required, string) is the name of the feed, which will often correspond to /// the name of the website (blog, for instance), though not necessarily. @@ -48,7 +74,7 @@ public struct JSONFeed { /// (optional but strongly recommended, string) is the URL of the feed, and /// serves as the unique identifier for the feed. As with home_page_url, this /// should be considered required for feeds on the public web. - public var feedUrl: String? + public var feedURL: String? /// (optional, string) provides more detail, beyond the title, on what the feed /// is about. A feed reader may display this text. @@ -65,7 +91,7 @@ public struct JSONFeed { /// probably won't use it very often. next_url must not be the same as /// feed_url, and it must not be the same as a previous next_url (to avoid /// infinite loops). - public var nextUrl: String? + public var nextURL: String? /// (optional, string) is the URL of an image for the feed suitable to be used /// in a timeline, much the way an avatar might be used. It should be square @@ -101,32 +127,12 @@ public struct JSONFeed { /// The JSONFeed items. public var items: [JSONFeedItem]? - public init( - title: String? = nil, - homePageURL: String? = nil, - feedUrl: String? = nil, - description: String? = nil, - userComment: String? = nil, - nextUrl: String? = nil, - icon: String? = nil, - favicon: String? = nil, - author: JSONFeedAuthor? = nil, - expired: Bool? = nil, - hubs: [JSONFeedHub]? = nil, - items: [JSONFeedItem]? = nil) { - self.title = title - self.homePageURL = homePageURL - self.feedUrl = feedUrl - self.description = description - self.userComment = userComment - self.nextUrl = nextUrl - self.icon = icon - self.favicon = favicon - self.author = author - self.expired = expired - self.hubs = hubs - self.items = items - } + // MARK: Internal + + /// (required, string) is the URL of the version of the format the feed + /// uses. This should appear at the very top, though we recognize that not all + /// JSON generators allow for ordering. + var version: String = "https://jsonfeed.org/version/1" } // MARK: - Sendable @@ -167,8 +173,8 @@ extension JSONFeed: Codable { try container.encodeIfPresent(userComment, forKey: .user_comment) try container.encodeIfPresent(homePageURL, forKey: .home_page_url) try container.encodeIfPresent(description, forKey: .description) - try container.encodeIfPresent(feedUrl, forKey: .feed_url) - try container.encodeIfPresent(nextUrl, forKey: .next_url) + try container.encodeIfPresent(feedURL, forKey: .feed_url) + try container.encodeIfPresent(nextURL, forKey: .next_url) try container.encodeIfPresent(icon, forKey: .icon) try container.encodeIfPresent(favicon, forKey: .favicon) try container.encodeIfPresent(expired, forKey: .expired) @@ -184,8 +190,8 @@ extension JSONFeed: Codable { userComment = try values.decodeIfPresent(String.self, forKey: .user_comment) homePageURL = try values.decodeIfPresent(String.self, forKey: .home_page_url) description = try values.decodeIfPresent(String.self, forKey: .description) - feedUrl = try values.decodeIfPresent(String.self, forKey: .feed_url) - nextUrl = try values.decodeIfPresent(String.self, forKey: .next_url) + feedURL = try values.decodeIfPresent(String.self, forKey: .feed_url) + nextURL = try values.decodeIfPresent(String.self, forKey: .next_url) icon = try values.decodeIfPresent(String.self, forKey: .icon) favicon = try values.decodeIfPresent(String.self, forKey: .favicon) expired = try values.decodeIfPresent(Bool.self, forKey: .expired) @@ -197,16 +203,16 @@ extension JSONFeed: Codable { extension JSONFeed: FeedInitializable { public init(data: Data) throws { - let formatter = RFC3339DateFormatter() - let decoder = JSONDecoder() + let formatter: RFC3339DateFormatter = .init() + let decoder: JSONDecoder = .init() decoder.dateDecodingStrategy = .formatted(formatter) self = try decoder.decode(JSONFeed.self, from: data) } } -extension JSONFeed { - public func toJSONString(formatted: Bool) throws -> String { - let encoder = JSONEncoder() +public extension JSONFeed { + func toJSONString(formatted: Bool) throws -> String { + let encoder: JSONEncoder = .init() encoder.dateEncodingStrategy = .formatted(RFC3339DateFormatter()) encoder.outputFormatting = formatted ? [.prettyPrinted] : [] let data = try encoder.encode(self) diff --git a/Sources/FeedKit/Feeds/JSON/JSONFeedAttachment.swift b/Sources/FeedKit/Feeds/JSON/JSONFeedAttachment.swift index e3cc854..bc29a98 100644 --- a/Sources/FeedKit/Feeds/JSON/JSONFeedAttachment.swift +++ b/Sources/FeedKit/Feeds/JSON/JSONFeedAttachment.swift @@ -1,31 +1,48 @@ // -// JSONFeedAttachment.swift +// JSONFeedAttachment.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Describes optional attatchments of a JSON Feed item. public struct JSONFeedAttachment { + // MARK: Lifecycle + + public init( + url: String? = nil, + mimeType: String? = nil, + title: String? = nil, + sizeInBytes: Int? = nil, + durationInSeconds: TimeInterval? = nil + ) { + self.url = url + self.mimeType = mimeType + self.title = title + self.sizeInBytes = sizeInBytes + self.durationInSeconds = durationInSeconds + } + + // MARK: Public + /// (required, string) specifies the location of the attachment. public var url: String? @@ -46,19 +63,6 @@ public struct JSONFeedAttachment { /// (optional, number) specifies how long it takes to listen to or watch, when /// played at normal speed. public var durationInSeconds: TimeInterval? - - public init( - url: String? = nil, - mimeType: String? = nil, - title: String? = nil, - sizeInBytes: Int? = nil, - durationInSeconds: TimeInterval? = nil) { - self.url = url - self.mimeType = mimeType - self.title = title - self.sizeInBytes = sizeInBytes - self.durationInSeconds = durationInSeconds - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/JSON/JSONFeedAuthor.swift b/Sources/FeedKit/Feeds/JSON/JSONFeedAuthor.swift index 694096a..81f790a 100644 --- a/Sources/FeedKit/Feeds/JSON/JSONFeedAuthor.swift +++ b/Sources/FeedKit/Feeds/JSON/JSONFeedAuthor.swift @@ -1,26 +1,25 @@ // -// JSONFeedAuthor.swift +// JSONFeedAuthor.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,6 +27,20 @@ import Foundation /// members. These are all optional - but if you provide an author object, then at /// least one is required: public struct JSONFeedAuthor { + // MARK: Lifecycle + + public init( + name: String? = nil, + url: String? = nil, + avatar: String? = nil + ) { + self.name = name + self.url = url + self.avatar = avatar + } + + // MARK: Public + /// (optional, string) is the author's name. public var name: String? @@ -42,15 +55,6 @@ public struct JSONFeedAuthor { /// use transparency where appropriate, since it may be rendered on a non-white /// background. public var avatar: String? - - public init( - name: String? = nil, - url: String? = nil, - avatar: String? = nil) { - self.name = name - self.url = url - self.avatar = avatar - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/JSON/JSONFeedHub.swift b/Sources/FeedKit/Feeds/JSON/JSONFeedHub.swift index 1f57561..860d66f 100644 --- a/Sources/FeedKit/Feeds/JSON/JSONFeedHub.swift +++ b/Sources/FeedKit/Feeds/JSON/JSONFeedHub.swift @@ -1,26 +1,25 @@ // -// JSONFeedHub.swift +// JSONFeedHub.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,18 +27,23 @@ import Foundation /// from the publisher of this feed. Each object has a type and url, both of which /// are required. public struct JSONFeedHub { - /// The protocol used to talk with the hub, such as "rssCloud" or "WebSub." - public var type: String? - - /// The hub's url. - public var url: String? + // MARK: Lifecycle public init( type: String? = nil, - url: String? = nil) { + url: String? = nil + ) { self.type = type self.url = url } + + // MARK: Public + + /// The protocol used to talk with the hub, such as "rssCloud" or "WebSub." + public var type: String? + + /// The hub's url. + public var url: String? } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/JSON/JSONFeedItem.swift b/Sources/FeedKit/Feeds/JSON/JSONFeedItem.swift index 0ba2dc4..1d780d5 100644 --- a/Sources/FeedKit/Feeds/JSON/JSONFeedItem.swift +++ b/Sources/FeedKit/Feeds/JSON/JSONFeedItem.swift @@ -1,32 +1,67 @@ // -// JSONFeedItem.swift +// JSONFeedItem.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// An individual item of a JSON Feed, acting as a container for metadata and data /// associated with the item. public struct JSONFeedItem { + // MARK: Lifecycle + + public init( + id: String? = nil, + url: String? = nil, + externalURL: String? = nil, + title: String? = nil, + contentText: String? = nil, + contentHtml: String? = nil, + summary: String? = nil, + image: String? = nil, + bannerImage: String? = nil, + datePublished: Date? = nil, + dateModified: Date? = nil, + author: JSONFeedAuthor? = nil, + tags: [String]? = nil, + attachments: [JSONFeedAttachment]? = nil + ) { + self.id = id + self.url = url + self.externalURL = externalURL + self.title = title + self.contentText = contentText + self.contentHtml = contentHtml + self.summary = summary + self.image = image + self.bannerImage = bannerImage + self.datePublished = datePublished + self.dateModified = dateModified + self.author = author + self.tags = tags + self.attachments = attachments + } + + // MARK: Public + /// (required, string) is unique for that item for that feed over time. If an /// item is ever updated, the id should be unchanged. New items should never /// use a previously-used id. If an id is presented as a number or other type, @@ -43,7 +78,7 @@ public struct JSONFeedItem { /// (very optional, string) is the URL of a page elsewhere. This is especially /// useful for linkblogs. If url links to where you're talking about a thing, /// then external_url links to the thing you're talking about. - public var externalUrl: String? + public var externalURL: String? /// (optional, string) is plain text. Microblog items in particular may omit /// titles. @@ -103,37 +138,6 @@ public struct JSONFeedItem { /// (optional, array) lists related resources. public var attachments: [JSONFeedAttachment]? - - public init( - id: String? = nil, - url: String? = nil, - externalUrl: String? = nil, - title: String? = nil, - contentText: String? = nil, - contentHtml: String? = nil, - summary: String? = nil, - image: String? = nil, - bannerImage: String? = nil, - datePublished: Date? = nil, - dateModified: Date? = nil, - author: JSONFeedAuthor? = nil, - tags: [String]? = nil, - attachments: [JSONFeedAttachment]? = nil) { - self.id = id - self.url = url - self.externalUrl = externalUrl - self.title = title - self.contentText = contentText - self.contentHtml = contentHtml - self.summary = summary - self.image = image - self.bannerImage = bannerImage - self.datePublished = datePublished - self.dateModified = dateModified - self.author = author - self.tags = tags - self.attachments = attachments - } } // MARK: - Sendable @@ -173,7 +177,7 @@ extension JSONFeedItem: Codable { try container.encodeIfPresent(id, forKey: .id) try container.encodeIfPresent(title, forKey: .title) try container.encodeIfPresent(url, forKey: .url) - try container.encodeIfPresent(externalUrl, forKey: .external_url) + try container.encodeIfPresent(externalURL, forKey: .external_url) try container.encodeIfPresent(contentText, forKey: .content_text) try container.encodeIfPresent(contentHtml, forKey: .content_html) try container.encodeIfPresent(summary, forKey: .summary) @@ -196,7 +200,7 @@ extension JSONFeedItem: Codable { } title = try values.decodeIfPresent(String.self, forKey: .title) url = try values.decodeIfPresent(String.self, forKey: .url) - externalUrl = try values.decodeIfPresent(String.self, forKey: .external_url) + externalURL = try values.decodeIfPresent(String.self, forKey: .external_url) contentText = try values.decodeIfPresent(String.self, forKey: .content_text) contentHtml = try values.decodeIfPresent(String.self, forKey: .content_html) summary = try values.decodeIfPresent(String.self, forKey: .summary) diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeed.swift b/Sources/FeedKit/Feeds/RSS/RSSFeed.swift index 2ec4183..f8caab8 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeed.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeed.swift @@ -1,26 +1,25 @@ // -// RSSFeed.swift +// RSSFeed.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -36,6 +35,14 @@ import XMLKit /// Subordinate to the element is a single element, which /// contains information about the channel (metadata) and its contents. public struct RSSFeed { + // MARK: Lifecycle + + public init(channel: RSSFeedChannel? = nil) { + self.channel = channel + } + + // MARK: Public + /// Represents the element in an RSS 2.0 document. /// /// The element provides metadata about the feed, such as the @@ -43,10 +50,6 @@ public struct RSSFeed { /// feed contains. This property is optional, as an RSS document may not /// always include a valid element. public var channel: RSSFeedChannel? - - public init(channel: RSSFeedChannel? = nil) { - self.channel = channel - } } // MARK: - Sendable @@ -89,7 +92,7 @@ extension RSSFeed: FeedInitializable {} extension RSSFeed: XMLDocumentConvertible { public func toXmlDocument() throws -> XMLKit.XMLDocument { - let encoder = XMLEncoder() + let encoder: XMLEncoder = .init() encoder.dateEncodingStrategy = .formatter(FeedDateFormatter(spec: .rfc822)) let document = try encoder.encode(value: self) @@ -109,7 +112,7 @@ extension RSSFeed: XMLDocumentConvertible { // MARK: - XMLStringConvertible extension RSSFeed: XMLStringConvertible { - public func toXMLString(formatted: Bool, indentationLevel: Int = 1) throws -> String { + public func toXMLString(formatted _: Bool, indentationLevel _: Int = 1) throws -> String { try toXmlDocument().toXMLString(formatted: true) } } diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedCategory.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedCategory.swift index cc29816..04f8aae 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedCategory.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedCategory.swift @@ -1,38 +1,41 @@ // -// RSSFeedCategory.swift +// RSSFeedCategory.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct RSSFeedCategoryAttributes: Codable, Equatable, Hashable, Sendable { - /// A string that identifies a categorization taxonomy. It's an optional - /// attribute of ``. e.g. "http://www.fool.com/cusips" - public var domain: String? + // MARK: Lifecycle public init(domain: String? = nil) { self.domain = domain } + + // MARK: Public + + /// A string that identifies a categorization taxonomy. It's an optional + /// attribute of ``. e.g. "http://www.fool.com/cusips" + public var domain: String? } /// The category of ``. Identifies a category or tag to which the feed diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedChannel.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedChannel.swift index 05ab4e2..65dde92 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedChannel.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedChannel.swift @@ -1,26 +1,25 @@ // -// RSSFeed.swift +// RSSFeedChannel.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -35,6 +34,62 @@ import Foundation /// Subordinate to the element is a single element, which /// contains information about the channel (metadata) and its contents. public struct RSSFeedChannel { + // MARK: Lifecycle + + public init( + title: String? = nil, + link: String? = nil, + description: String? = nil, + language: String? = nil, + copyright: String? = nil, + managingEditor: String? = nil, + webMaster: String? = nil, + pubDate: Date? = nil, + lastBuildDate: Date? = nil, + categories: [RSSFeedCategory]? = nil, + generator: String? = nil, + docs: String? = nil, + cloud: RSSFeedCloud? = nil, + rating: String? = nil, + ttl: Int? = nil, + image: RSSFeedImage? = nil, + textInput: RSSFeedTextInput? = nil, + skipHours: RSSFeedSkipHours? = nil, + skipDays: RSSFeedSkipDays? = nil, + items: [RSSFeedItem]? = nil, + dublinCore: DublinCore? = nil, + iTunes: ITunes? = nil, + syndication: Syndication? = nil, + atom: Atom? = nil + ) { + self.title = title + self.link = link + self.description = description + self.language = language + self.copyright = copyright + self.managingEditor = managingEditor + self.webMaster = webMaster + self.pubDate = pubDate + self.lastBuildDate = lastBuildDate + self.categories = categories + self.generator = generator + self.docs = docs + self.cloud = cloud + self.rating = rating + self.ttl = ttl + self.image = image + self.textInput = textInput + self.skipHours = skipHours + self.skipDays = skipDays + self.items = items + self.dublinCore = dublinCore + self.iTunes = iTunes + self.syndication = syndication + self.atom = atom + } + + // MARK: Public + /// The name of the channel. It's how people refer to your service. If /// you have an HTML website that contains the same information as your /// RSS file, the title of your channel should be the same as the title @@ -247,62 +302,11 @@ public struct RSSFeedChannel { /// /// See http://web.resource.org/rss/1.0/modules/syndication/ public var syndication: Syndication? - + /// Atom namespace in an RSS feed helps WebSub subscribers discover the topic /// and hub information. /// See https://www.w3.org/TR/websub/#discovery public var atom: Atom? - - public init( - title: String? = nil, - link: String? = nil, - description: String? = nil, - language: String? = nil, - copyright: String? = nil, - managingEditor: String? = nil, - webMaster: String? = nil, - pubDate: Date? = nil, - lastBuildDate: Date? = nil, - categories: [RSSFeedCategory]? = nil, - generator: String? = nil, - docs: String? = nil, - cloud: RSSFeedCloud? = nil, - rating: String? = nil, - ttl: Int? = nil, - image: RSSFeedImage? = nil, - textInput: RSSFeedTextInput? = nil, - skipHours: RSSFeedSkipHours? = nil, - skipDays: RSSFeedSkipDays? = nil, - items: [RSSFeedItem]? = nil, - dublinCore: DublinCore? = nil, - iTunes: ITunes? = nil, - syndication: Syndication? = nil, - atom: Atom? = nil) { - self.title = title - self.link = link - self.description = description - self.language = language - self.copyright = copyright - self.managingEditor = managingEditor - self.webMaster = webMaster - self.pubDate = pubDate - self.lastBuildDate = lastBuildDate - self.categories = categories - self.generator = generator - self.docs = docs - self.cloud = cloud - self.rating = rating - self.ttl = ttl - self.image = image - self.textInput = textInput - self.skipHours = skipHours - self.skipDays = skipDays - self.items = items - self.dublinCore = dublinCore - self.iTunes = iTunes - self.syndication = syndication - self.atom = atom - } } // MARK: - Sendable @@ -344,7 +348,7 @@ extension RSSFeedChannel: Codable { case dublinCore = "dc" case iTunes = "itunes" case syndication = "sy" - case atom = "atom" + case atom } public init(from decoder: any Decoder) throws { diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedCloud.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedCloud.swift index a79bb8f..75a56e9 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedCloud.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedCloud.swift @@ -1,32 +1,49 @@ // -// RSSFeedCloud.swift +// RSSFeedCloud.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit /// The attributes of the ``'s `` element. public struct RSSFeedCloudAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + domain: String? = nil, + port: Int? = nil, + path: String? = nil, + registerProcedure: String? = nil, + protocol: String? = nil + ) { + self.domain = domain + self.port = port + self.path = path + self.registerProcedure = registerProcedure + self.protocol = `protocol` + } + + // MARK: Public + /// The domain to register notification to. public var domain: String? @@ -44,19 +61,6 @@ public struct RSSFeedCloudAttributes: Codable, Equatable, Hashable, Sendable { /// is used instead and refers to the `protocol` attribute of the `cloud` /// element. public var `protocol`: String? - - public init( - domain: String? = nil, - port: Int? = nil, - path: String? = nil, - registerProcedure: String? = nil, - protocol: String? = nil) { - self.domain = domain - self.port = port - self.path = path - self.registerProcedure = registerProcedure - self.protocol = `protocol` - } } /// Allows processes to register with a cloud to be notified of updates to diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedEnclosure.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedEnclosure.swift index 8a24f88..fc54b8b 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedEnclosure.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedEnclosure.swift @@ -1,31 +1,44 @@ // -// RSSFeedEnclosure.swift +// RSSFeedEnclosure.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct RSSFeedEnclosureAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + url: String? = nil, + length: Int64? = nil, + type: String? = nil + ) { + self.url = url + self.length = length + self.type = type + } + + // MARK: Public + /// Where the enclosure is located. /// /// Example: http://www.scripting.com/mp3s/weatherReportSuite.mp3 @@ -40,15 +53,6 @@ public struct RSSFeedEnclosureAttributes: Codable, Equatable, Hashable, Sendable /// /// Example: audio/mpeg public var type: String? - - public init( - url: String? = nil, - length: Int64? = nil, - type: String? = nil) { - self.url = url - self.length = length - self.type = type - } } /// Describes a media object that is attached to the item. diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedGUID.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedGUID.swift index 74c241c..348180c 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedGUID.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedGUID.swift @@ -1,31 +1,38 @@ // -// RSSFeedGUID.swift +// RSSFeedGUID.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct RSSFeedGUIDAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(isPermaLink: Bool? = nil) { + self.isPermaLink = isPermaLink + } + + // MARK: Public + /// If the guid element has an attribute named "isPermaLink" with a value of /// true, the reader may assume that it is a permalink to the item, that is, /// a url that can be opened in a Web browser, that points to the full item @@ -37,10 +44,6 @@ public struct RSSFeedGUIDAttributes: Codable, Equatable, Hashable, Sendable { /// the guid may not be assumed to be a url, or a url to anything in /// particular. public var isPermaLink: Bool? - - public init(isPermaLink: Bool? = nil) { - self.isPermaLink = isPermaLink - } } /// A string that uniquely identifies the item. diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedImage.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedImage.swift index aa6778f..47042f7 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedImage.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedImage.swift @@ -1,26 +1,25 @@ // -// RSSFeedImage.swift +// RSSFeedImage.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -47,6 +46,26 @@ import Foundation /// /// Maximum value for height is 400, default value is 31. public struct RSSFeedImage { + // MARK: Lifecycle + + public init( + url: String? = nil, + title: String? = nil, + link: String? = nil, + width: Int? = nil, + height: Int? = nil, + description: String? = nil + ) { + self.url = url + self.title = title + self.link = link + self.width = width + self.height = height + self.description = description + } + + // MARK: Public + /// The URL of a GIF, JPEG or PNG image that represents the channel. public var url: String? @@ -70,21 +89,6 @@ public struct RSSFeedImage { /// Contains text that is included in the TITLE attribute of the link formed /// around the image in the HTML rendering. public var description: String? - - public init( - url: String? = nil, - title: String? = nil, - link: String? = nil, - width: Int? = nil, - height: Int? = nil, - description: String? = nil) { - self.url = url - self.title = title - self.link = link - self.width = width - self.height = height - self.description = description - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift index 3b7df61..42c5458 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedItem.swift @@ -1,26 +1,25 @@ // -// RSSFeedItem.swift +// RSSFeedItem.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -33,6 +32,42 @@ import Foundation /// the link and title may be omitted. All elements of an item are optional, /// however at least one of title or description must be present. public struct RSSFeedItem { + // MARK: Lifecycle + + public init( + title: String? = nil, + link: String? = nil, + description: String? = nil, + author: String? = nil, + categories: [RSSFeedCategory]? = nil, + comments: String? = nil, + enclosure: RSSFeedEnclosure? = nil, + guid: RSSFeedGUID? = nil, + pubDate: Date? = nil, + source: RSSFeedSource? = nil, + dublinCore: DublinCore? = nil, + content: Content? = nil, + iTunes: ITunes? = nil, + media: Media? = nil + ) { + self.title = title + self.link = link + self.description = description + self.author = author + self.categories = categories + self.comments = comments + self.enclosure = enclosure + self.guid = guid + self.pubDate = pubDate + self.source = source + self.dublinCore = dublinCore + self.content = content + self.iTunes = iTunes + self.media = media + } + + // MARK: Public + /// The title of the item. /// /// Example: Venice Film Festival Tries to Quit Sinking @@ -184,41 +219,10 @@ public struct RSSFeedItem { /// iTunes Podcasting Tags are de facto standard for podcast syndication. /// See https://help.apple.com/itc/podcasts_connect/#/itcb54353390 public var iTunes: ITunes? - + /// Media RSS is a new RSS module that supplements the /// capabilities of RSS 2.0. public var media: Media? - - public init( - title: String? = nil, - link: String? = nil, - description: String? = nil, - author: String? = nil, - categories: [RSSFeedCategory]? = nil, - comments: String? = nil, - enclosure: RSSFeedEnclosure? = nil, - guid: RSSFeedGUID? = nil, - pubDate: Date? = nil, - source: RSSFeedSource? = nil, - dublinCore: DublinCore? = nil, - content: Content? = nil, - iTunes: ITunes? = nil, - media: Media? = nil) { - self.title = title - self.link = link - self.description = description - self.author = author - self.categories = categories - self.comments = comments - self.enclosure = enclosure - self.guid = guid - self.pubDate = pubDate - self.source = source - self.dublinCore = dublinCore - self.content = content - self.iTunes = iTunes - self.media = media - } } // MARK: - Sendable @@ -248,9 +252,9 @@ extension RSSFeedItem: Codable { case pubDate case source case dublinCore = "dc" - case content = "content" + case content case iTunes = "itunes" - case media = "media" + case media } public init(from decoder: any Decoder) throws { diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedSkipDay.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedSkipDay.swift index 288f7d5..9fe4339 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedSkipDay.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedSkipDay.swift @@ -1,26 +1,25 @@ // -// RSSFeedSkipDay.swift +// RSSFeedSkipDay.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -48,12 +47,12 @@ public enum RSSFeedSkipDay: String, Equatable, Hashable, Codable, Sendable { case sunday } -extension RSSFeedSkipDay { +public extension RSSFeedSkipDay { /// Lowercase the incoming `rawValue` string to try and match the /// `SkipDay`'s `rawValue` /// /// - Parameter rawValue: The raw value - public init?(rawValue: String) { + init?(rawValue: String) { switch rawValue.lowercased() { case "monday": self = .monday case "tuesday": self = .tuesday diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedSkipHours.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedSkipHours.swift index 1d68165..6df0710 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedSkipHours.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedSkipHours.swift @@ -1,26 +1,25 @@ // -// RSSFeedSkipHours.swift +// RSSFeedSkipHours.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedSource.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedSource.swift index 356554b..752e0ff 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedSource.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedSource.swift @@ -1,38 +1,41 @@ // -// RSSFeedSource.swift +// RSSFeedSource.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct RSSFeedSourceAttributes: Codable, Equatable, Hashable, Sendable { - /// Required attribute of the `Source` element, which links to the - /// XMLization of the source. e.g. "http://www.tomalak.org/links2.xml" - public var url: String? + // MARK: Lifecycle public init(url: String? = nil) { self.url = url } + + // MARK: Public + + /// Required attribute of the `Source` element, which links to the + /// XMLization of the source. e.g. "http://www.tomalak.org/links2.xml" + public var url: String? } /// The RSS channel that the item came from. diff --git a/Sources/FeedKit/Feeds/RSS/RSSFeedTextInput.swift b/Sources/FeedKit/Feeds/RSS/RSSFeedTextInput.swift index e29c010..dc4086d 100644 --- a/Sources/FeedKit/Feeds/RSS/RSSFeedTextInput.swift +++ b/Sources/FeedKit/Feeds/RSS/RSSFeedTextInput.swift @@ -1,26 +1,25 @@ // -// RSSFeedTextInput.swift +// RSSFeedTextInput.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -41,6 +40,22 @@ import Foundation /// use it to specify a search engine box. Or to allow a reader to provide /// feedback. Most aggregators ignore it. public struct RSSFeedTextInput { + // MARK: Lifecycle + + public init( + title: String? = nil, + description: String? = nil, + name: String? = nil, + link: String? = nil + ) { + self.title = title + self.description = description + self.name = name + self.link = link + } + + // MARK: Public + /// The label of the Submit button in the text input area. public var title: String? @@ -52,17 +67,6 @@ public struct RSSFeedTextInput { /// The URL of the CGI script that processes text input requests. public var link: String? - - public init( - title: String? = nil, - description: String? = nil, - name: String? = nil, - link: String? = nil) { - self.title = title - self.description = description - self.name = name - self.link = link - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Atom/Atom.swift b/Sources/FeedKit/Namespaces/Atom/Atom.swift index a952859..3448b65 100644 --- a/Sources/FeedKit/Namespaces/Atom/Atom.swift +++ b/Sources/FeedKit/Namespaces/Atom/Atom.swift @@ -1,26 +1,25 @@ // -// Atom.swift +// Atom.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -29,14 +28,18 @@ import XMLKit /// and hub information. /// See https://www.w3.org/TR/websub/#discovery public struct Atom { - /// The "atom:link" element defines a reference from an entry or feed to - /// a Web resource. This specification assigns no meaning to the content - /// (if any) of this element. - public var links: [AtomLink]? + // MARK: Lifecycle public init(links: [AtomLink]? = nil) { self.links = links } + + // MARK: Public + + /// The "atom:link" element defines a reference from an entry or feed to + /// a Web resource. This specification assigns no meaning to the content + /// (if any) of this element. + public var links: [AtomLink]? } // MARK: - XMLNamespaceDecodable diff --git a/Sources/FeedKit/Namespaces/Atom/AtomLink.swift b/Sources/FeedKit/Namespaces/Atom/AtomLink.swift index 5e0bee8..41a0296 100644 --- a/Sources/FeedKit/Namespaces/Atom/AtomLink.swift +++ b/Sources/FeedKit/Namespaces/Atom/AtomLink.swift @@ -1,31 +1,50 @@ // -// AtomLink.swift +// AtomLink.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct AtomLinkAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + href: String? = nil, + rel: String? = nil, + type: String? = nil, + hreflang: String? = nil, + title: String? = nil, + length: Int64? = nil + ) { + self.href = href + self.rel = rel + self.type = type + self.hreflang = hreflang + self.title = title + self.length = length + } + + // MARK: Public + /// The "href" attribute contains the link's IRI. atom:link elements MUST /// have an href attribute, whose value MUST be a IRI reference /// [RFC3987]. @@ -112,21 +131,6 @@ public struct AtomLinkAttributes: Codable, Equatable, Hashable, Sendable { /// by the underlying protocol. Link elements MAY have a length /// attribute. public var length: Int64? - - public init( - href: String? = nil, - rel: String? = nil, - type: String? = nil, - hreflang: String? = nil, - title: String? = nil, - length: Int64? = nil) { - self.href = href - self.rel = rel - self.type = type - self.hreflang = hreflang - self.title = title - self.length = length - } } /// The "atom:link" element defines a reference from an entry or feed to diff --git a/Sources/FeedKit/Namespaces/Content/Content.swift b/Sources/FeedKit/Namespaces/Content/Content.swift index db2ada3..4ee3187 100644 --- a/Sources/FeedKit/Namespaces/Content/Content.swift +++ b/Sources/FeedKit/Namespaces/Content/Content.swift @@ -1,26 +1,25 @@ // -// Content.swift +// Content.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -28,6 +27,14 @@ import XMLKit /// A module for the actual content of websites, in multiple formats. /// See http://web.resource.org/rss/1.0/modules/content/ public struct Content { + // MARK: Lifecycle + + public init(encoded: String? = nil) { + self.encoded = encoded + } + + // MARK: Public + /// An element whose contents are the entity-encoded or CDATA-escaped version /// of the content of the item. /// @@ -35,10 +42,6 @@ public struct Content { /// What a beautiful day!

]]> ///
public var encoded: String? - - public init(encoded: String? = nil) { - self.encoded = encoded - } } // MARK: - XMLNamespaceDecodable @@ -57,7 +60,6 @@ extension Content: Equatable {} extension Content: Hashable {} - // MARK: - Codable extension Content: Codable { diff --git a/Sources/FeedKit/Namespaces/DublinCore/DublinCore.swift b/Sources/FeedKit/Namespaces/DublinCore/DublinCore.swift index 54589b9..f5bd837 100644 --- a/Sources/FeedKit/Namespaces/DublinCore/DublinCore.swift +++ b/Sources/FeedKit/Namespaces/DublinCore/DublinCore.swift @@ -1,26 +1,25 @@ // -// DublinCore.swift +// DublinCore.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -30,6 +29,44 @@ import XMLKit /// /// See https://tools.ietf.org/html/rfc5013 public struct DublinCore { + // MARK: Lifecycle + + public init( + title: String? = nil, + creator: String? = nil, + subject: String? = nil, + description: String? = nil, + publisher: String? = nil, + contributor: String? = nil, + date: Date? = nil, + type: String? = nil, + format: String? = nil, + identifier: String? = nil, + source: String? = nil, + language: String? = nil, + relation: String? = nil, + coverage: String? = nil, + rights: String? = nil + ) { + self.title = title + self.creator = creator + self.subject = subject + self.description = description + self.publisher = publisher + self.contributor = contributor + self.date = date + self.type = type + self.format = format + self.identifier = identifier + self.source = source + self.language = language + self.relation = relation + self.coverage = coverage + self.rights = rights + } + + // MARK: Public + /// A name given to the resource. public var title: String? @@ -134,39 +171,6 @@ public struct DublinCore { /// rights associated with the resource, including intellectual property /// rights. public var rights: String? - - public init( - title: String? = nil, - creator: String? = nil, - subject: String? = nil, - description: String? = nil, - publisher: String? = nil, - contributor: String? = nil, - date: Date? = nil, - type: String? = nil, - format: String? = nil, - identifier: String? = nil, - source: String? = nil, - language: String? = nil, - relation: String? = nil, - coverage: String? = nil, - rights: String? = nil) { - self.title = title - self.creator = creator - self.subject = subject - self.description = description - self.publisher = publisher - self.contributor = contributor - self.date = date - self.type = type - self.format = format - self.identifier = identifier - self.source = source - self.language = language - self.relation = relation - self.coverage = coverage - self.rights = rights - } } // MARK: - XMLNamespaceDecodable diff --git a/Sources/FeedKit/Namespaces/GML/GMLPoint.swift b/Sources/FeedKit/Namespaces/GML/GMLPoint.swift index 831adc3..1cf9f40 100644 --- a/Sources/FeedKit/Namespaces/GML/GMLPoint.swift +++ b/Sources/FeedKit/Namespaces/GML/GMLPoint.swift @@ -1,26 +1,25 @@ // -// GMLPoint.swift +// GMLPoint.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,16 +27,20 @@ import Foundation /// Within the latitude and longitude coordinate values are separated /// by a space. public struct GMLPoint { + // MARK: Lifecycle + + public init(position: (latitude: Double, longitude: Double)? = nil) { + self.position = position + } + + // MARK: Public + /// The geographical position represented as latitude and longitude /// for a element. /// /// - The `position` is an optional tuple containing the latitude and longitude /// as `Double` values. If not provided, it defaults to `nil`. public var position: (latitude: Double, longitude: Double)? - - public init(position: (latitude: Double, longitude: Double)? = nil) { - self.position = position - } } // MARK: - Sendable @@ -78,7 +81,7 @@ extension GMLPoint: Codable { public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) - if let position = position { + if let position { let positionString = "\(position.latitude) \(position.longitude)" try container.encode(positionString, forKey: .position) } diff --git a/Sources/FeedKit/Namespaces/Geo/GeoRSS.swift b/Sources/FeedKit/Namespaces/Geo/GeoRSS.swift index eedba62..5b8a641 100644 --- a/Sources/FeedKit/Namespaces/Geo/GeoRSS.swift +++ b/Sources/FeedKit/Namespaces/Geo/GeoRSS.swift @@ -1,26 +1,25 @@ // -// GeoRSS.swift +// GeoRSS.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -29,14 +28,18 @@ import Foundation /// encoding location in an interoperable manner so that applications can request, /// aggregate, share and map geographically tag feeds. public struct GeoRSS { - /// A point consists of a GML element with a child element. - /// Within the latitude and longitude coordinate values are separated - /// by a space. - var gmlPoint: GMLPoint? + // MARK: Lifecycle public init(gmlPoint: GMLPoint? = nil) { self.gmlPoint = gmlPoint } + + // MARK: Internal + + /// A point consists of a GML element with a child element. + /// Within the latitude and longitude coordinate values are separated + /// by a space. + var gmlPoint: GMLPoint? } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/Media.swift b/Sources/FeedKit/Namespaces/Media/Media.swift index 130c380..b4692ec 100644 --- a/Sources/FeedKit/Namespaces/Media/Media.swift +++ b/Sources/FeedKit/Namespaces/Media/Media.swift @@ -1,26 +1,25 @@ // -// Media.swift +// Media.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -33,6 +32,68 @@ import XMLKit /// content publishers and bloggers to syndicate multimedia content /// such as TV and video clips, movies, images and audio. public struct Media { + // MARK: Lifecycle + + public init( + group: MediaGroup? = nil, + contents: [MediaContent]? = nil, + rating: MediaRating? = nil, + title: MediaTitle? = nil, + description: MediaDescription? = nil, + keywords: [String]? = nil, + thumbnails: [MediaThumbnail]? = nil, + category: MediaCategory? = nil, + hash: MediaHash? = nil, + player: MediaPlayer? = nil, + credits: [MediaCredit]? = nil, + copyright: MediaCopyright? = nil, + text: MediaText? = nil, + restriction: MediaRestriction? = nil, + community: MediaCommunity? = nil, + comments: MediaComments? = nil, + embed: MediaEmbed? = nil, + responses: MediaResponses? = nil, + backLinks: MediaBackLinks? = nil, + status: MediaStatus? = nil, + prices: [MediaPrice]? = nil, + license: MediaLicence? = nil, + subTitle: MediaSubTitle? = nil, + peerLink: MediaPeerLink? = nil, + location: MediaLocation? = nil, + rights: MediaRights? = nil, + scenes: MediaScenes? = nil + ) { + self.group = group + self.contents = contents + self.rating = rating + self.title = title + self.description = description + self.keywords = keywords + self.thumbnails = thumbnails + self.category = category + self.hash = hash + self.player = player + self.credits = credits + self.copyright = copyright + self.text = text + self.restriction = restriction + self.community = community + self.comments = comments + self.embed = embed + self.responses = responses + self.backLinks = backLinks + self.status = status + self.prices = prices + self.license = license + self.subTitle = subTitle + self.peerLink = peerLink + self.location = location + self.rights = rights + self.scenes = scenes + } + + // MARK: Public + /// The element is a sub-element of . It allows grouping /// of elements that are effectively the same content, /// yet different representations. For instance: the same song recorded @@ -171,63 +232,6 @@ public struct Media { /// and , which contains title, description, /// start and end time of a particular scene in the media, respectively. public var scenes: MediaScenes? - - public init( - group: MediaGroup? = nil, - contents: [MediaContent]? = nil, - rating: MediaRating? = nil, - title: MediaTitle? = nil, - description: MediaDescription? = nil, - keywords: [String]? = nil, - thumbnails: [MediaThumbnail]? = nil, - category: MediaCategory? = nil, - hash: MediaHash? = nil, - player: MediaPlayer? = nil, - credits: [MediaCredit]? = nil, - copyright: MediaCopyright? = nil, - text: MediaText? = nil, - restriction: MediaRestriction? = nil, - community: MediaCommunity? = nil, - comments: MediaComments? = nil, - embed: MediaEmbed? = nil, - responses: MediaResponses? = nil, - backLinks: MediaBackLinks? = nil, - status: MediaStatus? = nil, - prices: [MediaPrice]? = nil, - license: MediaLicence? = nil, - subTitle: MediaSubTitle? = nil, - peerLink: MediaPeerLink? = nil, - location: MediaLocation? = nil, - rights: MediaRights? = nil, - scenes: MediaScenes? = nil) { - self.group = group - self.contents = contents - self.rating = rating - self.title = title - self.description = description - self.keywords = keywords - self.thumbnails = thumbnails - self.category = category - self.hash = hash - self.player = player - self.credits = credits - self.copyright = copyright - self.text = text - self.restriction = restriction - self.community = community - self.comments = comments - self.embed = embed - self.responses = responses - self.backLinks = backLinks - self.status = status - self.prices = prices - self.license = license - self.subTitle = subTitle - self.peerLink = peerLink - self.location = location - self.rights = rights - self.scenes = scenes - } } // MARK: - XMLNamespaceDecodable diff --git a/Sources/FeedKit/Namespaces/Media/MediaBacklinks.swift b/Sources/FeedKit/Namespaces/Media/MediaBacklinks.swift index 00a45d2..d726bad 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaBacklinks.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaBacklinks.swift @@ -1,37 +1,40 @@ // -// MediaBackLinks.swift +// MediaBacklinks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Allows inclusion of all the URLs pointing to a media object. public struct MediaBackLinks { - /// Allows inclusion of all the URLs pointing to a media object. - public var backLinks: [String]? + // MARK: Lifecycle public init(backLinks: [String]? = nil) { self.backLinks = backLinks } + + // MARK: Public + + /// Allows inclusion of all the URLs pointing to a media object. + public var backLinks: [String]? } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaCategory.swift b/Sources/FeedKit/Namespaces/Media/MediaCategory.swift index 546efcd..5260351 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaCategory.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaCategory.swift @@ -1,31 +1,42 @@ // -// MediaCategory.swift +// MediaCategory.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaCategoryAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + scheme: String? = nil, + label: String? = nil + ) { + self.scheme = scheme + self.label = label + } + + // MARK: Public + /// The URI that identifies the categorization scheme. It is an optional /// attribute. If this attribute is not included, the default scheme /// is "http://search.yahoo.com/mrss/category_schema". @@ -34,13 +45,6 @@ public struct MediaCategoryAttributes: Codable, Equatable, Hashable, Sendable { /// The human readable label that can be displayed in end user /// applications. It is an optional attribute. public var label: String? - - public init( - scheme: String? = nil, - label: String? = nil) { - self.scheme = scheme - self.label = label - } } /// Allows a taxonomy to be set that gives an indication of the type of media diff --git a/Sources/FeedKit/Namespaces/Media/MediaComments.swift b/Sources/FeedKit/Namespaces/Media/MediaComments.swift index fe54f2e..ebf8b2e 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaComments.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaComments.swift @@ -1,38 +1,40 @@ // -// MediaComments.swift +// MediaComments.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Allows inclusion of all the comments a media object has received. public struct MediaComments { + // MARK: Lifecycle - /// Allows inclusion of all the comments a media object has received. - public var comments: [String]? - public init(comments: [String]? = nil) { self.comments = comments } + + // MARK: Public + + /// Allows inclusion of all the comments a media object has received. + public var comments: [String]? } // MARK: - Sendable @@ -50,22 +52,19 @@ extension MediaComments: Hashable {} // MARK: - Codable extension MediaComments: Codable { - private enum CodingKeys: String, CodingKey { case comment = "media:comment" } - + public init(from decoder: any Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self) - - self.comments = try container.decodeIfPresent([String].self, forKey: CodingKeys.comment) - + + comments = try container.decodeIfPresent([String].self, forKey: CodingKeys.comment) } - + public func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) - - try container.encodeIfPresent(self.comments, forKey: CodingKeys.comment) + + try container.encodeIfPresent(comments, forKey: CodingKeys.comment) } - } diff --git a/Sources/FeedKit/Namespaces/Media/MediaCommunity.swift b/Sources/FeedKit/Namespaces/Media/MediaCommunity.swift index 939646d..04632c6 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaCommunity.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaCommunity.swift @@ -1,26 +1,25 @@ // -// MediaCommunity.swift +// MediaCommunity.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,6 +27,20 @@ import Foundation /// inclusion of the user perception about a media object in the form of view /// count, ratings and tags. public struct MediaCommunity { + // MARK: Lifecycle + + public init( + starRating: MediaStarRating? = nil, + statistics: MediaStatistics? = nil, + tags: [MediaTag]? = nil + ) { + self.starRating = starRating + self.statistics = statistics + self.tags = tags + } + + // MARK: Public + /// This element specifies the rating-related information about a media object. /// Valid attributes are average, count, min and max. public var starRating: MediaStarRating? @@ -42,15 +55,6 @@ public struct MediaCommunity { /// weight is determined for a tag; for example, number of occurences can be /// one way to decide weight of a particular tag. Default weight is 1. public var tags: [MediaTag]? - - public init( - starRating: MediaStarRating? = nil, - statistics: MediaStatistics? = nil, - tags: [MediaTag]? = nil) { - self.starRating = starRating - self.statistics = statistics - self.tags = tags - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaContent.swift b/Sources/FeedKit/Namespaces/Media/MediaContent.swift index 7134a63..511bae7 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaContent.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaContent.swift @@ -1,26 +1,25 @@ // -// MediaContent.swift +// MediaContent.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -31,8 +30,74 @@ import Foundation /// audio/video specific, this element can be used to publish any type of /// media. It contains 14 attributes, most of which are optional. public struct MediaContent { + // MARK: Lifecycle + + public init( + attributes: Attributes? = nil, + title: MediaTitle? = nil, + description: MediaDescription? = nil, + player: MediaPlayer? = nil, + thumbnails: [MediaThumbnail]? = nil, + keywords: [String]? = nil, + category: MediaCategory? = nil, + credits: [MediaCredit]? = nil, + rating: MediaRating? = nil, + hash: MediaHash? = nil, + text: MediaText? = nil + ) { + self.attributes = attributes + self.title = title + self.description = description + self.player = player + self.thumbnails = thumbnails + self.keywords = keywords + self.category = category + self.credits = credits + self.rating = rating + self.hash = hash + self.text = text + } + + // MARK: Public + /// The element's attributes. public struct Attributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + url: String? = nil, + fileSize: Int? = nil, + type: String? = nil, + medium: String? = nil, + isDefault: Bool? = nil, + expression: String? = nil, + bitrate: Int? = nil, + framerate: Double? = nil, + samplingrate: Double? = nil, + channels: Int? = nil, + duration: Int? = nil, + height: Int? = nil, + width: Int? = nil, + lang: String? = nil + ) { + self.url = url + self.fileSize = fileSize + self.type = type + self.medium = medium + self.isDefault = isDefault + self.expression = expression + self.bitrate = bitrate + self.framerate = framerate + self.samplingrate = samplingrate + self.channels = channels + self.duration = duration + self.height = height + self.width = width + self.lang = lang + } + + // MARK: Public + /// Should specify the direct URL to the media object. If not included, /// a element must be specified. public var url: String? @@ -93,37 +158,6 @@ public struct MediaContent { /// XML 1.0 Specification (Third Edition). It is an optional /// attribute. public var lang: String? - - public init( - url: String? = nil, - fileSize: Int? = nil, - type: String? = nil, - medium: String? = nil, - isDefault: Bool? = nil, - expression: String? = nil, - bitrate: Int? = nil, - framerate: Double? = nil, - samplingrate: Double? = nil, - channels: Int? = nil, - duration: Int? = nil, - height: Int? = nil, - width: Int? = nil, - lang: String? = nil) { - self.url = url - self.fileSize = fileSize - self.type = type - self.medium = medium - self.isDefault = isDefault - self.expression = expression - self.bitrate = bitrate - self.framerate = framerate - self.samplingrate = samplingrate - self.channels = channels - self.duration = duration - self.height = height - self.width = width - self.lang = lang - } } /// The element's attributes @@ -163,31 +197,6 @@ public struct MediaContent { public var hash: MediaHash? public var text: MediaText? - - public init( - attributes: Attributes? = nil, - title: MediaTitle? = nil, - description: MediaDescription? = nil, - player: MediaPlayer? = nil, - thumbnails: [MediaThumbnail]? = nil, - keywords: [String]? = nil, - category: MediaCategory? = nil, - credits: [MediaCredit]? = nil, - rating: MediaRating? = nil, - hash: MediaHash? = nil, - text: MediaText? = nil) { - self.attributes = attributes - self.title = title - self.description = description - self.player = player - self.thumbnails = thumbnails - self.keywords = keywords - self.category = category - self.credits = credits - self.rating = rating - self.hash = hash - self.text = text - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaCopyright.swift b/Sources/FeedKit/Namespaces/Media/MediaCopyright.swift index 6f37d4d..84909cf 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaCopyright.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaCopyright.swift @@ -1,40 +1,43 @@ // -// MediaCopyright.swift +// MediaCopyright.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaCopyrightAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(url: String? = nil) { + self.url = url + } + + // MARK: Public + /// The URL for a terms of use page or additional copyright information. /// If the media is operating under a Creative Commons license, the /// Creative Commons module should be used instead. It is an optional /// attribute. public var url: String? - - public init(url: String? = nil) { - self.url = url - } } /// Copyright information for the media object. It has one optional attribute. diff --git a/Sources/FeedKit/Namespaces/Media/MediaCredit.swift b/Sources/FeedKit/Namespaces/Media/MediaCredit.swift index 8384287..7a65e29 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaCredit.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaCredit.swift @@ -1,31 +1,42 @@ // -// MediaCredit.swift +// MediaCredit.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaCreditAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + role: String? = nil, + scheme: String? = nil + ) { + self.role = role + self.scheme = scheme + } + + // MARK: Public + /// Specifies the role the entity played. Must be lowercase. It is an /// optional attribute. public var role: String? @@ -36,13 +47,6 @@ public struct MediaCreditAttributes: Codable, Equatable, Hashable, Sendable { /// scheme can be found at European Broadcasting Union Role Codes. The /// roles supported under urn:yvs scheme are ( uploader | owner ). public var scheme: String? - - public init( - role: String? = nil, - scheme: String? = nil) { - self.role = role - self.scheme = scheme - } } /// Notable entity and the contribution to the creation of the media object. diff --git a/Sources/FeedKit/Namespaces/Media/MediaDescription.swift b/Sources/FeedKit/Namespaces/Media/MediaDescription.swift index 82c6b61..531006a 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaDescription.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaDescription.swift @@ -1,39 +1,43 @@ // -// MediaDescription.swift +// MediaDescription.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaDescriptionAttributes: Codable, Equatable, Hashable, Sendable { - /// Specifies the type of text embedded. Possible values are either "plain" or "html". - /// Default value is "plain". All HTML must be entity-encoded. It is an optional attribute. - public var type: String? + // MARK: Lifecycle public init(type: String? = nil) { self.type = type } + + // MARK: Public + + /// Specifies the type of text embedded. Possible values are either "plain" or "html". + /// Default value is "plain". All HTML must be entity-encoded. It is an optional attribute. + public var type: String? } + /// Short description describing the media object typically a sentence in /// length. It has one optional attribute. public typealias MediaDescription = XMLKit.XMLElement diff --git a/Sources/FeedKit/Namespaces/Media/MediaEmbed.swift b/Sources/FeedKit/Namespaces/Media/MediaEmbed.swift index 2fd3dd5..f0af559 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaEmbed.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaEmbed.swift @@ -1,26 +1,25 @@ // -// MediaEmbed.swift +// MediaEmbed.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,25 +27,42 @@ import Foundation /// video. allows inclusion of such information in the form of /// key-value pairs. public struct MediaEmbed { - /// The element's attributes. - public struct Attributes: Codable, Equatable, Hashable, Sendable { - /// The location of the embeded media. - public var url: String? + // MARK: Lifecycle - /// The width size for the embeded Media. - public var width: Int? + public init( + attributes: Attributes? = nil, + params: [MediaParam]? = nil + ) { + self.attributes = attributes + self.params = params + } - /// The height size for the embeded Media. - public var height: Int? + // MARK: Public + + /// The element's attributes. + public struct Attributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle public init( url: String? = nil, width: Int? = nil, - height: Int? = nil) { + height: Int? = nil + ) { self.url = url self.width = width self.height = height } + + // MARK: Public + + /// The location of the embeded media. + public var url: String? + + /// The width size for the embeded Media. + public var width: Int? + + /// The height size for the embeded Media. + public var height: Int? } /// The element's attributes. @@ -54,13 +70,6 @@ public struct MediaEmbed { /// Key-Value pairs with aditional parameters for the embeded Media. public var params: [MediaParam]? - - public init( - attributes: Attributes? = nil, - params: [MediaParam]? = nil) { - self.attributes = attributes - self.params = params - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaGroup.swift b/Sources/FeedKit/Namespaces/Media/MediaGroup.swift index f86a8c5..bae86c6 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaGroup.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaGroup.swift @@ -1,26 +1,25 @@ // -// MediaGroup.swift +// MediaGroup.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -30,6 +29,22 @@ import Foundation /// in both the WAV and MP3 format. It's an optional element that must /// only be used for this purpose. public struct MediaGroup { + // MARK: Lifecycle + + public init( + contents: [MediaContent]? = nil, + credits: [MediaCredit]? = nil, + category: MediaCategory? = nil, + rating: MediaRating? = nil + ) { + self.contents = contents + self.credits = credits + self.category = category + self.rating = rating + } + + // MARK: Public + /// is a sub-element of either or . /// Media objects that are not the same content should not be included /// in the same element. The sequence of these items implies @@ -53,17 +68,6 @@ public struct MediaGroup { /// included, it assumes that no restrictions are necessary. It has one /// optional attribute. public var rating: MediaRating? - - public init( - contents: [MediaContent]? = nil, - credits: [MediaCredit]? = nil, - category: MediaCategory? = nil, - rating: MediaRating? = nil) { - self.contents = contents - self.credits = credits - self.category = category - self.rating = rating - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaHash.swift b/Sources/FeedKit/Namespaces/Media/MediaHash.swift index 64f9033..6c29f90 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaHash.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaHash.swift @@ -1,38 +1,41 @@ // -// MediaHash.swift +// MediaHash.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaHashAttributes: Codable, Equatable, Hashable, Sendable { - /// This is the hash of the binary media file. It can appear multiple times as long as - /// each instance is a different algo. It has one optional attribute. - public var algo: String? + // MARK: Lifecycle public init(algo: String? = nil) { self.algo = algo } + + // MARK: Public + + /// This is the hash of the binary media file. It can appear multiple times as long as + /// each instance is a different algo. It has one optional attribute. + public var algo: String? } /// This is the hash of the binary media file. It can appear multiple times as diff --git a/Sources/FeedKit/Namespaces/Media/MediaLicence.swift b/Sources/FeedKit/Namespaces/Media/MediaLicence.swift index 91441c8..672f677 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaLicence.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaLicence.swift @@ -1,41 +1,44 @@ // -// MediaLicence.swift +// MediaLicence.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaLicenceAttributes: Codable, Equatable, Hashable, Sendable { - /// The licence type. - public var type: String? - - /// The location of the licence. - public var href: String? + // MARK: Lifecycle public init(type: String? = nil, href: String? = nil) { self.type = type self.href = href } + + // MARK: Public + + /// The licence type. + public var type: String? + + /// The location of the licence. + public var href: String? } /// Optional link to specify the machine-readable license associated with the diff --git a/Sources/FeedKit/Namespaces/Media/MediaLocation.swift b/Sources/FeedKit/Namespaces/Media/MediaLocation.swift index 954e93a..bab7568 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaLocation.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaLocation.swift @@ -1,26 +1,25 @@ // -// MediaLocation.swift +// MediaLocation.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -28,18 +27,21 @@ import Foundation /// locations captured in the content of a media object. The format conforms /// to geoRSS. public struct MediaLocation { - /// The element's attributes. - public struct Attributes: Codable, Equatable, Hashable, Sendable { - /// Description of the place whose location is being specified. - public var description: String? + // MARK: Lifecycle - /// Time at which the reference to a particular location starts in the - /// media object. - public var start: TimeInterval? + public init( + attributes: Attributes? = nil, + geoRSS: GeoRSS? = nil + ) { + self.attributes = attributes + self.geoRSS = geoRSS + } - /// Time at which the reference to a particular location ends in the media - /// object. - public var end: TimeInterval? + // MARK: Public + + /// The element's attributes. + public struct Attributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle public init(description: String? = nil, start: TimeInterval? = nil, end: TimeInterval? = nil) { self.description = description @@ -47,12 +49,6 @@ public struct MediaLocation { self.end = end } - private enum CodingKeys: CodingKey { - case description - case start - case end - } - public init(from decoder: any Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -61,6 +57,19 @@ public struct MediaLocation { end = try container.decodeIfPresent(String.self, forKey: CodingKeys.end)?.toDuration() } + // MARK: Public + + /// Description of the place whose location is being specified. + public var description: String? + + /// Time at which the reference to a particular location starts in the + /// media object. + public var start: TimeInterval? + + /// Time at which the reference to a particular location ends in the media + /// object. + public var end: TimeInterval? + public func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) @@ -68,6 +77,14 @@ public struct MediaLocation { try container.encodeIfPresent(start, forKey: CodingKeys.start) try container.encodeIfPresent(end, forKey: CodingKeys.end) } + + // MARK: Private + + private enum CodingKeys: CodingKey { + case description + case start + case end + } } /// The element's attributes @@ -78,13 +95,6 @@ public struct MediaLocation { /// encoding location in an interoperable manner so that applications can request, /// aggregate, share and map geographically tag feeds. public var geoRSS: GeoRSS? - - public init( - attributes: Attributes? = nil, - geoRSS: GeoRSS? = nil) { - self.attributes = attributes - self.geoRSS = geoRSS - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaParam.swift b/Sources/FeedKit/Namespaces/Media/MediaParam.swift index 1369394..c75cbbc 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaParam.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaParam.swift @@ -1,37 +1,40 @@ // -// MediaParam.swift +// MediaParam.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaParamAttributes: Codable, Equatable, Hashable, Sendable { - /// The parameter's key name. - public var name: String? + // MARK: Lifecycle public init(name: String? = nil) { self.name = name } + + // MARK: Public + + /// The parameter's key name. + public var name: String? } /// Key-Value pairs with additional parameters for the embedded Media. diff --git a/Sources/FeedKit/Namespaces/Media/MediaPeerLink.swift b/Sources/FeedKit/Namespaces/Media/MediaPeerLink.swift index 8540f6d..2b18c77 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaPeerLink.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaPeerLink.swift @@ -1,41 +1,44 @@ // -// MediaPeerLink.swift +// MediaPeerLink.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaPeerLinkAttributes: Codable, Equatable, Hashable, Sendable { - /// The peer link's type. - public var type: String? - - /// The location of the peer link provider. - public var href: String? + // MARK: Lifecycle public init(type: String? = nil, href: String? = nil) { self.type = type self.href = href } + + // MARK: Public + + /// The peer link's type. + public var type: String? + + /// The location of the peer link provider. + public var href: String? } /// Optional element for P2P link. diff --git a/Sources/FeedKit/Namespaces/Media/MediaPlayer.swift b/Sources/FeedKit/Namespaces/Media/MediaPlayer.swift index 9adb4dd..faeb0ef 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaPlayer.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaPlayer.swift @@ -1,31 +1,40 @@ // -// MediaPlayer.swift +// MediaPlayer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaPlayerAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init(url: String? = nil, width: Int? = nil, height: Int? = nil) { + self.url = url + self.width = width + self.height = height + } + + // MARK: Public + /// The URL of the player console that plays the media. It is a required attribute. public var url: String? @@ -36,12 +45,6 @@ public struct MediaPlayerAttributes: Codable, Equatable, Hashable, Sendable { /// The height of the browser window that the URL should be opened in. It is an /// optional attribute. public var height: Int? - - public init(url: String? = nil, width: Int? = nil, height: Int? = nil) { - self.url = url - self.width = width - self.height = height - } } /// Allows the media object to be accessed through a web browser media player diff --git a/Sources/FeedKit/Namespaces/Media/MediaPrice.swift b/Sources/FeedKit/Namespaces/Media/MediaPrice.swift index 5b404e4..e9db9b4 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaPrice.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaPrice.swift @@ -1,31 +1,46 @@ // -// MediaPrice.swift +// MediaPrice.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaPriceAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + type: String? = nil, + price: Double? = nil, + info: String? = nil, + currency: String? = nil + ) { + self.type = type + self.price = price + self.info = info + self.currency = currency + } + + // MARK: Public + /// Valid values are "rent", "purchase", "package" or "subscription". If /// nothing is specified, then the media is free. public var type: String? @@ -39,17 +54,6 @@ public struct MediaPriceAttributes: Codable, Equatable, Hashable, Sendable { /// Use [ISO 4217] for currency codes. This is an optional attribute. public var currency: String? - - public init( - type: String? = nil, - price: Double? = nil, - info: String? = nil, - currency: String? = nil) { - self.type = type - self.price = price - self.info = info - self.currency = currency - } } /// Optional tag to include pricing information about a media object. If this diff --git a/Sources/FeedKit/Namespaces/Media/MediaRating.swift b/Sources/FeedKit/Namespaces/Media/MediaRating.swift index ebaf15d..03a283c 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaRating.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaRating.swift @@ -1,38 +1,41 @@ // -// MediaRating.swift +// MediaRating.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaRatingAttributes: Codable, Equatable, Hashable, Sendable { - /// The URI that identifies the rating scheme. It is an optional attribute. - /// If this attribute is not included, the default scheme is urn:simple (adult | nonadult). - public var scheme: String? + // MARK: Lifecycle public init(scheme: String? = nil) { self.scheme = scheme } + + // MARK: Public + + /// The URI that identifies the rating scheme. It is an optional attribute. + /// If this attribute is not included, the default scheme is urn:simple (adult | nonadult). + public var scheme: String? } /// This allows the permissible audience to be declared. If this element is not diff --git a/Sources/FeedKit/Namespaces/Media/MediaReponses.swift b/Sources/FeedKit/Namespaces/Media/MediaReponses.swift index 868cdd4..c99f895 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaReponses.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaReponses.swift @@ -1,39 +1,42 @@ // -// MediaResponses.swift +// MediaReponses.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Allows inclusion of a list of all media responses a media object has /// received. public struct MediaResponses { - /// Allows inclusion of a list of all media responses a media object has - /// received. - public var responses: [String]? + // MARK: Lifecycle public init(responses: [String]? = nil) { self.responses = responses } + + // MARK: Public + + /// Allows inclusion of a list of all media responses a media object has + /// received. + public var responses: [String]? } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaRestriction.swift b/Sources/FeedKit/Namespaces/Media/MediaRestriction.swift index 53cf762..3479e89 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaRestriction.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaRestriction.swift @@ -1,31 +1,42 @@ // -// MediaRestriction.swift +// MediaRestriction.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaRestrictionAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + relationship: String? = nil, + type: String? = nil + ) { + self.relationship = relationship + self.type = type + } + + // MARK: Public + /// Indicates the type of relationship that the restriction represents /// (allow | deny). In the example above, the media object should only be /// syndicated in Australia and the United States. It is a required @@ -40,13 +51,6 @@ public struct MediaRestrictionAttributes: Codable, Equatable, Hashable, Sendable /// media can be syndicated. It is an optional attribute; however can only /// be excluded when using one of the literal values "all" or "none". public var type: String? - - public init( - relationship: String? = nil, - type: String? = nil) { - self.relationship = relationship - self.type = type - } } /// Allows restrictions to be placed on the aggregator rendering the media in diff --git a/Sources/FeedKit/Namespaces/Media/MediaRights.swift b/Sources/FeedKit/Namespaces/Media/MediaRights.swift index 4cb150a..a93d752 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaRights.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaRights.swift @@ -1,39 +1,42 @@ // -// MediaRights.swift +// MediaRights.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaRightsAttributes: Codable, Equatable, Hashable, Sendable { - /// Is the status of the media object saying whether a media object has - /// been created by the publisher or they have rights to circulate it. - /// Supported values are "userCreated" and "official". - public var status: String? + // MARK: Lifecycle public init(status: String? = nil) { self.status = status } + + // MARK: Public + + /// Is the status of the media object saying whether a media object has + /// been created by the publisher or they have rights to circulate it. + /// Supported values are "userCreated" and "official". + public var status: String? } /// Optional element to specify the rights information of a media object. diff --git a/Sources/FeedKit/Namespaces/Media/MediaScene.swift b/Sources/FeedKit/Namespaces/Media/MediaScene.swift index 0102b9f..4f698f2 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaScene.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaScene.swift @@ -1,26 +1,25 @@ // -// MediaScene.swift +// MediaScene.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -31,6 +30,22 @@ import Foundation /// and , which contains title, description, /// start and end time of a particular scene in the media, respectively. public struct MediaScene { + // MARK: Lifecycle + + public init( + title: String? = nil, + description: String? = nil, + startTime: TimeInterval? = nil, + endTime: TimeInterval? = nil + ) { + self.title = title + self.description = description + self.startTime = startTime + self.endTime = endTime + } + + // MARK: Public + /// The scene's title. public var title: String? @@ -42,17 +57,6 @@ public struct MediaScene { /// The scene's end time. public var endTime: TimeInterval? - - public init( - title: String? = nil, - description: String? = nil, - startTime: TimeInterval? = nil, - endTime: TimeInterval? = nil) { - self.title = title - self.description = description - self.startTime = startTime - self.endTime = endTime - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaScenes.swift b/Sources/FeedKit/Namespaces/Media/MediaScenes.swift index a299174..25b880c 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaScenes.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaScenes.swift @@ -1,26 +1,25 @@ // -// MediaScene.swift +// MediaScenes.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/FeedKit/Namespaces/Media/MediaStarRating.swift b/Sources/FeedKit/Namespaces/Media/MediaStarRating.swift index 3912dda..7e72244 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaStarRating.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaStarRating.swift @@ -1,31 +1,46 @@ // -// MediaStarRating.swift +// MediaStarRating.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaStarRatingAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + average: Double? = nil, + count: Int? = nil, + min: Int? = nil, + max: Int? = nil + ) { + self.average = average + self.count = count + self.min = min + self.max = max + } + + // MARK: Public + /// The star rating's average. public var average: Double? @@ -37,17 +52,6 @@ public struct MediaStarRatingAttributes: Codable, Equatable, Hashable, Sendable /// The star rating's maximum value. public var max: Int? - - public init( - average: Double? = nil, - count: Int? = nil, - min: Int? = nil, - max: Int? = nil) { - self.average = average - self.count = count - self.min = min - self.max = max - } } /// This element specifies the rating-related information about a media object. diff --git a/Sources/FeedKit/Namespaces/Media/MediaStatistics.swift b/Sources/FeedKit/Namespaces/Media/MediaStatistics.swift index 2041e72..ec8a7cb 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaStatistics.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaStatistics.swift @@ -1,43 +1,47 @@ // -// MediaStatistics.swift +// MediaStatistics.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaStatisticsAttributes: Codable, Equatable, Hashable, Sendable { - /// The number of views. - public var views: Int? - - /// The number fo favorites. - public var favorites: Int? + // MARK: Lifecycle public init( views: Int? = nil, - favorites: Int? = nil) { + favorites: Int? = nil + ) { self.views = views self.favorites = favorites } + + // MARK: Public + + /// The number of views. + public var views: Int? + + /// The number fo favorites. + public var favorites: Int? } /// This element specifies various statistics about a media object like the diff --git a/Sources/FeedKit/Namespaces/Media/MediaStatus.swift b/Sources/FeedKit/Namespaces/Media/MediaStatus.swift index cec3bbb..c0b3a23 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaStatus.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaStatus.swift @@ -1,31 +1,42 @@ // -// MediaStatus.swift +// MediaStatus.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaStatusAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + state: String? = nil, + reason: String? = nil + ) { + self.state = state + self.reason = reason + } + + // MARK: Public + /// State can have values "active", "blocked" or "deleted". "active" means /// a media object is active in the system, "blocked" means a media object /// is blocked by the publisher, "deleted" means a media object has been @@ -35,13 +46,6 @@ public struct MediaStatusAttributes: Codable, Equatable, Hashable, Sendable { /// A reason explaining why a media object has been blocked/deleted. It can /// be plain text or a URL. public var reason: String? - - public init( - state: String? = nil, - reason: String? = nil) { - self.state = state - self.reason = reason - } } /// Optional tag to specify the status of a media object -- whether it's still diff --git a/Sources/FeedKit/Namespaces/Media/MediaSubTitle.swift b/Sources/FeedKit/Namespaces/Media/MediaSubTitle.swift index 15bbd63..ff2cc73 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaSubTitle.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaSubTitle.swift @@ -1,48 +1,52 @@ // -// MediaSubTitle.swift +// MediaSubTitle.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaSubTitleAttributes: Codable, Equatable, Hashable, Sendable { - /// The type of the subtitle. - public var type: String? - - /// The subtitle language based on the RFC 3066. - public var lang: String? - - /// The location of the subtitle. - public var href: String? + // MARK: Lifecycle public init( type: String? = nil, lang: String? = nil, - href: String? = nil) { + href: String? = nil + ) { self.type = type self.lang = lang self.href = href } + + // MARK: Public + + /// The type of the subtitle. + public var type: String? + + /// The subtitle language based on the RFC 3066. + public var lang: String? + + /// The location of the subtitle. + public var href: String? } /// Optional link to specify the machine-readable license associated with the diff --git a/Sources/FeedKit/Namespaces/Media/MediaTag.swift b/Sources/FeedKit/Namespaces/Media/MediaTag.swift index acb97fc..dde4190 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaTag.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaTag.swift @@ -1,26 +1,25 @@ // -// MediaTag.swift +// MediaTag.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -30,18 +29,23 @@ import Foundation /// determined for a tag; for example, number of occurrences can be one way to /// decide weight of a particular tag. Default weight is 1. public struct MediaTag { - /// The tag name. - public var tag: String? - - /// The tag weight. Default to 1 if not specified. - public var weight: Int = 1 + // MARK: Lifecycle public init( tag: String? = nil, - weight: Int = 1) { + weight: Int = 1 + ) { self.tag = tag self.weight = weight } + + // MARK: Public + + /// The tag name. + public var tag: String? + + /// The tag weight. Default to 1 if not specified. + public var weight: Int = 1 } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/Media/MediaText.swift b/Sources/FeedKit/Namespaces/Media/MediaText.swift index e09b6c4..c022af8 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaText.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaText.swift @@ -1,31 +1,46 @@ // -// MediaText.swift +// MediaText.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaTextAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + type: String? = nil, + lang: String? = nil, + start: String? = nil, + end: String? = nil + ) { + self.type = type + self.lang = lang + self.start = start + self.end = end + } + + // MARK: Public + /// Specifies the type of text embedded. Possible values are either "plain" /// or "html". Default value is "plain". All HTML must be entity-encoded. /// It is an optional attribute. @@ -48,17 +63,6 @@ public struct MediaTextAttributes: Codable, Equatable, Hashable, Sendable { /// time is either the end of the clip or the start of the next /// element. public var end: String? - - public init( - type: String? = nil, - lang: String? = nil, - start: String? = nil, - end: String? = nil) { - self.type = type - self.lang = lang - self.start = start - self.end = end - } } /// Allows the inclusion of a text transcript, closed captioning or lyrics of diff --git a/Sources/FeedKit/Namespaces/Media/MediaThumbnail.swift b/Sources/FeedKit/Namespaces/Media/MediaThumbnail.swift index 0a94c7a..3095a00 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaThumbnail.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaThumbnail.swift @@ -1,31 +1,46 @@ // -// MediaThumbnail.swift +// MediaThumbnail.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaThumbnailAttributes: Codable, Equatable, Hashable, Sendable { + // MARK: Lifecycle + + public init( + url: String? = nil, + width: String? = nil, + height: String? = nil, + time: String? = nil + ) { + self.url = url + self.width = width + self.height = height + self.time = time + } + + // MARK: Public + /// Specifies the url of the thumbnail. It is a required attribute. public var url: String? @@ -40,17 +55,6 @@ public struct MediaThumbnailAttributes: Codable, Equatable, Hashable, Sendable { /// for this attribute should be in the DSM-CC's Normal Play Time (NTP) as used in /// RTSP [RFC 2326 3.6 Normal Play Time]. It is an optional attribute. public var time: String? - - public init( - url: String? = nil, - width: String? = nil, - height: String? = nil, - time: String? = nil) { - self.url = url - self.width = width - self.height = height - self.time = time - } } /// Allows particular images to be used as representative images for the diff --git a/Sources/FeedKit/Namespaces/Media/MediaTitle.swift b/Sources/FeedKit/Namespaces/Media/MediaTitle.swift index 48ba9ff..2bee8a6 100644 --- a/Sources/FeedKit/Namespaces/Media/MediaTitle.swift +++ b/Sources/FeedKit/Namespaces/Media/MediaTitle.swift @@ -1,38 +1,41 @@ // -// MediaTitle.swift +// MediaTitle.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct MediaTitleAttributes: Codable, Equatable, Hashable, Sendable { - /// Specifies the type of text embedded. Possible values are either "plain" or "html". - /// Default value is "plain". All HTML must be entity-encoded. It is an optional attribute. - public var type: String? + // MARK: Lifecycle public init(type: String? = nil) { self.type = type } + + // MARK: Public + + /// Specifies the type of text embedded. Possible values are either "plain" or "html". + /// Default value is "plain". All HTML must be entity-encoded. It is an optional attribute. + public var type: String? } /// The title of the particular media object. It has one optional attribute. diff --git a/Sources/FeedKit/Namespaces/Syndication/Syndication.swift b/Sources/FeedKit/Namespaces/Syndication/Syndication.swift index 1dc424b..3f45702 100644 --- a/Sources/FeedKit/Namespaces/Syndication/Syndication.swift +++ b/Sources/FeedKit/Namespaces/Syndication/Syndication.swift @@ -1,26 +1,25 @@ // -// Syndication.swift +// Syndication.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -34,6 +33,20 @@ import XMLKit /// /// See http://web.resource.org/rss/1.0/modules/syndication/ public struct Syndication { + // MARK: Lifecycle + + public init( + updatePeriod: SyndicationUpdatePeriod? = nil, + updateFrequency: Int? = nil, + updateBase: Date? = nil + ) { + self.updatePeriod = updatePeriod + self.updateFrequency = updateFrequency + self.updateBase = updateBase + } + + // MARK: Public + /// Describes the period over which the channel format is updated. Acceptable /// values are: hourly, daily, weekly, monthly, yearly. If omitted, daily is /// assumed. @@ -50,15 +63,6 @@ public struct Syndication { /// updateFrequency to calculate the publishing schedule. The date format takes /// the form: yyyy-mm-ddThh:mm public var updateBase: Date? - - public init( - updatePeriod: SyndicationUpdatePeriod? = nil, - updateFrequency: Int? = nil, - updateBase: Date? = nil) { - self.updatePeriod = updatePeriod - self.updateFrequency = updateFrequency - self.updateBase = updateBase - } } // MARK: - XMLNamespaceDecodable diff --git a/Sources/FeedKit/Namespaces/Syndication/SyndicationUpdatePeriod.swift b/Sources/FeedKit/Namespaces/Syndication/SyndicationUpdatePeriod.swift index 1badf09..1aa3ace 100644 --- a/Sources/FeedKit/Namespaces/Syndication/SyndicationUpdatePeriod.swift +++ b/Sources/FeedKit/Namespaces/Syndication/SyndicationUpdatePeriod.swift @@ -1,26 +1,25 @@ // -// SyndicationUpdatePeriod.swift +// SyndicationUpdatePeriod.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -49,12 +48,12 @@ public enum SyndicationUpdatePeriod: String { case yearly } -extension SyndicationUpdatePeriod { +public extension SyndicationUpdatePeriod { /// Lowercase the incoming `rawValue` string to try and match the /// `SyUpdatePeriod`'s `rawValue` /// /// - Parameter rawValue: The raw value. - public init?(rawValue: String) { + init?(rawValue: String) { switch rawValue.lowercased() { case "hourly": self = .hourly case "daily": self = .daily diff --git a/Sources/FeedKit/Namespaces/YouTube/Youtube.swift b/Sources/FeedKit/Namespaces/YouTube/Youtube.swift index 8c7c5f7..16898d9 100644 --- a/Sources/FeedKit/Namespaces/YouTube/Youtube.swift +++ b/Sources/FeedKit/Namespaces/YouTube/Youtube.swift @@ -1,26 +1,25 @@ // -// YouTube.swift +// Youtube.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -29,18 +28,23 @@ import XMLKit /// /// See https://developers.google.com/youtube/v3/guides/push_notifications public struct YouTube { - /// The element's value to identify the channel that owns that video. - public var channelID: String? - - /// The element's value to identify the newly added or updated video. - public var videoID: String? + // MARK: Lifecycle public init( channelID: String? = nil, - videoID: String? = nil) { + videoID: String? = nil + ) { self.channelID = channelID self.videoID = videoID } + + // MARK: Public + + /// The element's value to identify the channel that owns that video. + public var channelID: String? + + /// The element's value to identify the newly added or updated video. + public var videoID: String? } // MARK: - XMLNamespaceDecodable @@ -62,25 +66,22 @@ extension YouTube: Hashable {} // MARK: - Codable extension YouTube: Codable { - private enum CodingKeys: String, CodingKey { case channelID = "yt:channelId" case videoID = "yt:videoId" } - + public init(from decoder: any Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: YouTube.CodingKeys.self) - - self.channelID = try container.decodeIfPresent(String.self, forKey: YouTube.CodingKeys.channelID) - self.videoID = try container.decodeIfPresent(String.self, forKey: YouTube.CodingKeys.videoID) - + + channelID = try container.decodeIfPresent(String.self, forKey: YouTube.CodingKeys.channelID) + videoID = try container.decodeIfPresent(String.self, forKey: YouTube.CodingKeys.videoID) } - + public func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: YouTube.CodingKeys.self) - - try container.encodeIfPresent(self.channelID, forKey: YouTube.CodingKeys.channelID) - try container.encodeIfPresent(self.videoID, forKey: YouTube.CodingKeys.videoID) - } + try container.encodeIfPresent(channelID, forKey: YouTube.CodingKeys.channelID) + try container.encodeIfPresent(videoID, forKey: YouTube.CodingKeys.videoID) + } } diff --git a/Sources/FeedKit/Namespaces/iTunes/ITunes.swift b/Sources/FeedKit/Namespaces/iTunes/ITunes.swift index 79275d6..c9f3c55 100644 --- a/Sources/FeedKit/Namespaces/iTunes/ITunes.swift +++ b/Sources/FeedKit/Namespaces/iTunes/ITunes.swift @@ -1,26 +1,25 @@ // -// iTunes.swift +// ITunes.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit @@ -28,6 +27,52 @@ import XMLKit /// iTunes Podcasting Tags are de facto standard for podcast syndication. For more /// information see https://help.apple.com/itc/podcasts_connect/#/itcb54353390 public struct ITunes { + // MARK: Lifecycle + + public init( + author: String? = nil, + block: String? = nil, + categories: [iTunesCategory]? = nil, + image: iTunesImage? = nil, + duration: TimeInterval? = nil, + explicit: String? = nil, + isClosedCaptioned: String? = nil, + order: Int? = nil, + complete: String? = nil, + newFeedURL: String? = nil, + owner: iTunesOwner? = nil, + title: String? = nil, + subtitle: String? = nil, + summary: String? = nil, + keywords: String? = nil, + type: String? = nil, + episodeType: String? = nil, + season: Int? = nil, + episode: Int? = nil + ) { + self.author = author + self.block = block + self.categories = categories + self.image = image + self.duration = duration + self.explicit = explicit + self.isClosedCaptioned = isClosedCaptioned + self.order = order + self.complete = complete + self.newFeedURL = newFeedURL + self.owner = owner + self.title = title + self.subtitle = subtitle + self.summary = summary + self.keywords = keywords + self.type = type + self.episodeType = episodeType + self.season = season + self.episode = episode + } + + // MARK: Public + /// The content you specify in the tag appears in the Artist /// column on the iTunes Store. If the tag is not present, the iTunes Store /// uses the contents of the tag. If is not present @@ -240,47 +285,6 @@ public struct ITunes { /// Use the tag in conjunction with the tag /// to indicate the order an episode should be presented within a season. public var episode: Int? - - public init( - author: String? = nil, - block: String? = nil, - categories: [iTunesCategory]? = nil, - image: iTunesImage? = nil, - duration: TimeInterval? = nil, - explicit: String? = nil, - isClosedCaptioned: String? = nil, - order: Int? = nil, - complete: String? = nil, - newFeedURL: String? = nil, - owner: iTunesOwner? = nil, - title: String? = nil, - subtitle: String? = nil, - summary: String? = nil, - keywords: String? = nil, - type: String? = nil, - episodeType: String? = nil, - season: Int? = nil, - episode: Int? = nil) { - self.author = author - self.block = block - self.categories = categories - self.image = image - self.duration = duration - self.explicit = explicit - self.isClosedCaptioned = isClosedCaptioned - self.order = order - self.complete = complete - self.newFeedURL = newFeedURL - self.owner = owner - self.title = title - self.subtitle = subtitle - self.summary = summary - self.keywords = keywords - self.type = type - self.episodeType = episodeType - self.season = season - self.episode = episode - } } // MARK: - XMLNamespaceDecodable diff --git a/Sources/FeedKit/Namespaces/iTunes/iTunesCategory.swift b/Sources/FeedKit/Namespaces/iTunes/iTunesCategory.swift index a0b7613..878f15a 100644 --- a/Sources/FeedKit/Namespaces/iTunes/iTunesCategory.swift +++ b/Sources/FeedKit/Namespaces/iTunes/iTunesCategory.swift @@ -1,26 +1,25 @@ // -// iTunesCategory.swift +// iTunesCategory.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -56,14 +55,30 @@ import Foundation /// /// public struct iTunesCategory { + // MARK: Lifecycle + + public init( + attributes: Attributes? = nil, + subcategory: iTunesSubCategory? = nil + ) { + self.attributes = attributes + self.subcategory = subcategory + } + + // MARK: Public + /// The attributes of the element. public struct Attributes: Codable, Equatable, Hashable, Sendable { - /// The primary iTunes Category. - public var text: String? + // MARK: Lifecycle public init(text: String? = nil) { self.text = text } + + // MARK: Public + + /// The primary iTunes Category. + public var text: String? } /// The element's attributes. @@ -71,13 +86,6 @@ public struct iTunesCategory { /// The iTunes SubCategory. public var subcategory: iTunesSubCategory? - - public init( - attributes: Attributes? = nil, - subcategory: iTunesSubCategory? = nil) { - self.attributes = attributes - self.subcategory = subcategory - } } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/iTunes/iTunesImage.swift b/Sources/FeedKit/Namespaces/iTunes/iTunesImage.swift index da6fee1..585f74f 100644 --- a/Sources/FeedKit/Namespaces/iTunes/iTunesImage.swift +++ b/Sources/FeedKit/Namespaces/iTunes/iTunesImage.swift @@ -1,37 +1,40 @@ // -// ITunesImage.swift +// iTunesImage.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct iTunesImageAttributes: Codable, Equatable, Hashable, Sendable { - /// The image's url. - public var href: String? + // MARK: Lifecycle public init(href: String? = nil) { self.href = href } + + // MARK: Public + + /// The image's url. + public var href: String? } /// Specify your podcast artwork using the attribute in the diff --git a/Sources/FeedKit/Namespaces/iTunes/iTunesOwner.swift b/Sources/FeedKit/Namespaces/iTunes/iTunesOwner.swift index 3c72a90..729aa7c 100644 --- a/Sources/FeedKit/Namespaces/iTunes/iTunesOwner.swift +++ b/Sources/FeedKit/Namespaces/iTunes/iTunesOwner.swift @@ -1,26 +1,25 @@ // -// iTunesOwner.swift +// iTunesOwner.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -31,18 +30,23 @@ import Foundation /// The tag information is for administrative communication about /// the podcast and is not displayed on the iTunes Store. public struct iTunesOwner { - /// The email address of the owner. - public var email: String? - - /// The name of the owner. - public var name: String? + // MARK: Lifecycle public init( email: String? = nil, - name: String? = nil) { + name: String? = nil + ) { self.email = email self.name = name } + + // MARK: Public + + /// The email address of the owner. + public var email: String? + + /// The name of the owner. + public var name: String? } // MARK: - Sendable diff --git a/Sources/FeedKit/Namespaces/iTunes/iTunesSubCategory.swift b/Sources/FeedKit/Namespaces/iTunes/iTunesSubCategory.swift index 99581ac..fa2bbb2 100644 --- a/Sources/FeedKit/Namespaces/iTunes/iTunesSubCategory.swift +++ b/Sources/FeedKit/Namespaces/iTunes/iTunesSubCategory.swift @@ -1,37 +1,40 @@ // -// ITunesSubCategory.swift +// iTunesSubCategory.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import XMLKit public struct iTunesSubCategoryAttributes: Codable, Equatable, Hashable, Sendable { - /// The primary iTunes Category. - public var text: String? + // MARK: Lifecycle public init(text: String? = nil) { self.text = text } + + // MARK: Public + + /// The primary iTunes Category. + public var text: String? } /// Users can browse podcast subject categories in the iTunes Store by choosing diff --git a/Sources/XMLKit/XMLDecoder/XMLDateDecodingStrategy.swift b/Sources/XMLKit/XMLDecoder/XMLDateDecodingStrategy.swift index 41cf6e8..9401c06 100644 --- a/Sources/XMLKit/XMLDecoder/XMLDateDecodingStrategy.swift +++ b/Sources/XMLKit/XMLDecoder/XMLDateDecodingStrategy.swift @@ -1,26 +1,25 @@ // -// XMLDateDecodingStrategy.swift +// XMLDateDecodingStrategy.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/XMLKit/XMLDecoder/XMLDecoder.swift b/Sources/XMLKit/XMLDecoder/XMLDecoder.swift index def01a9..1f37e6c 100644 --- a/Sources/XMLKit/XMLDecoder/XMLDecoder.swift +++ b/Sources/XMLKit/XMLDecoder/XMLDecoder.swift @@ -1,36 +1,52 @@ // -// XMLDecoder.swift +// XMLDecoder.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation public class XMLDecoder { + // MARK: Lifecycle + /// Creates a new instance of `XMLDecoder`. public init() {} + // MARK: Public + /// The strategy for decoding `Date` values from XML nodes. public var dateDecodingStrategy: XMLDateDecodingStrategy = .deferredToDate + public func decode(_ type: T.Type, from data: Data) throws -> T where T: Decodable { + let reader: XMLReader = .init(data: data) + let result = try reader.read().get() + + guard let rootNode = result.root else { + throw XMLError.unexpected(reason: "Unexpected parsing result. Root is nil.") + } + + return try decode(type, from: rootNode) + } + + // MARK: Internal + /// Decodes a top-level value of the given type from the given XML representation. /// /// - parameter type: The type of the value to decode. @@ -39,34 +55,16 @@ public class XMLDecoder { /// - throws: `DecodingError.dataCorrupted` if values requested from the payload /// are corrupted, or if the given data is not valid XML. /// - throws: An error if any value throws an error during decoding. - func decode(_ type: T.Type, from node: XMLNode) throws -> T where T: Decodable { - let decoder = _XMLDecoder(node: node, codingPath: []) + func decode(_: T.Type, from node: XMLNode) throws -> T where T: Decodable { + let decoder: _XMLDecoder = .init(node: node, codingPath: []) decoder.dateDecodingStrategy = dateDecodingStrategy return try T(from: decoder) } - - public func decode(_ type: T.Type, from data: Data) throws -> T where T: Decodable { - let reader = XMLReader(data: data) - let result = try reader.read().get() - - guard let rootNode = result.root else { - throw XMLError.unexpected(reason: "Unexpected parsing result. Root is nil.") - } - - return try decode(type, from: rootNode) - } } /// A decoder for XML data that uses a stack-based parsing approach. class _XMLDecoder: Decoder { - /// The stack used for managing XML elements during decoding. - var stack: XMLStack - /// The path of coding keys used to locate a value in the decoding process. - var codingPath: [any CodingKey] - /// User-defined contextual information for the decoding process. - var userInfo: [CodingUserInfoKey: Any] - /// The strategy for decoding `Date` values from XML nodes. - var dateDecodingStrategy: XMLDateDecodingStrategy = .deferredToDate + // MARK: Lifecycle /// Initializes the decoder with a root element and optional coding path. /// - Parameters: @@ -79,11 +77,22 @@ class _XMLDecoder: Decoder { userInfo = [:] } + // MARK: Internal + + /// The stack used for managing XML elements during decoding. + var stack: XMLStack + /// The path of coding keys used to locate a value in the decoding process. + var codingPath: [any CodingKey] + /// User-defined contextual information for the decoding process. + var userInfo: [CodingUserInfoKey: Any] + /// The strategy for decoding `Date` values from XML nodes. + var dateDecodingStrategy: XMLDateDecodingStrategy = .deferredToDate + /// Returns a keyed decoding container for the current XML element. /// - Parameter type: The type of the coding key. /// - Returns: A keyed decoding container for the specified key type. /// - Throws: An error if the container cannot be created. - func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { + func container(keyedBy _: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { KeyedDecodingContainer(XMLKeyedDecodingContainer( decoder: self, node: stack.top()! @@ -135,7 +144,7 @@ class _XMLDecoder: Decoder { /// - type: The expected type, which must be `Date`. /// - Returns: A decoded `Date` instance. /// - Throws: A `DecodingError` if the date cannot be decoded. - func decode(node: XMLNode, as type: Date.Type) throws -> Date { + func decode(node: XMLNode, as _: Date.Type) throws -> Date { switch dateDecodingStrategy { case .deferredToDate: return try Date(from: self) @@ -144,7 +153,8 @@ class _XMLDecoder: Decoder { defer { stack.pop() } guard let stringDate = node.text, - let date = formatter.date(from: stringDate) else { + let date = formatter.date(from: stringDate) + else { throw DecodingError.dataCorrupted(.init( codingPath: codingPath, debugDescription: "Unable to decode date with formatter: \(formatter)" @@ -180,11 +190,12 @@ class _XMLDecoder: Decoder { /// - Returns: A decoded value of the specified type. /// - Throws: A `DecodingError.dataCorrupted` error if the element's text is /// missing or cannot be converted to the specified type. - func decode(_ node: XMLNode, as type: T.Type, for key: Key) throws -> T { + func decode(_ node: XMLNode, as type: T.Type, for key: some CodingKey) throws -> T { guard let child = node.child(for: key.stringValue), let text = child.text, - let value = T(text) else { + let value = T(text) + else { throw DecodingError.dataCorrupted(.init( codingPath: codingPath, debugDescription: "Failed to decode \(type) value from key: \(key.stringValue)" diff --git a/Sources/XMLKit/XMLDecoder/XMLKeyedDecodingContainer.swift b/Sources/XMLKit/XMLDecoder/XMLKeyedDecodingContainer.swift index 079ce0d..bcca404 100644 --- a/Sources/XMLKit/XMLDecoder/XMLKeyedDecodingContainer.swift +++ b/Sources/XMLKit/XMLDecoder/XMLKeyedDecodingContainer.swift @@ -1,39 +1,30 @@ // -// XMLKeyedDecodingContainer.swift +// XMLKeyedDecodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol { - /// The XML decoder used for decoding the current element. - var decoder: _XMLDecoder - /// The current XML element being decoded. - var node: XMLNode - /// The coding path of the current decoding process. - var codingPath: [CodingKey] { decoder.codingPath } - /// This property is expected to contain all keys present in the current - /// XML element. However, it is not yet utilized. - var allKeys: [Key] = [] + // MARK: Lifecycle /// Initializes a keyed decoding container for an XML element. /// - Parameters: @@ -44,8 +35,21 @@ class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol self.node = node } + // MARK: Internal + + /// The XML decoder used for decoding the current element. + var decoder: _XMLDecoder + /// The current XML element being decoded. + var node: XMLNode + /// This property is expected to contain all keys present in the current + /// XML element. However, it is not yet utilized. + var allKeys: [Key] = [] + + /// The coding path of the current decoding process. + var codingPath: [CodingKey] { decoder.codingPath } + func contains(_ key: Key) -> Bool { - if key.stringValue == "@text" && node.text?.isEmpty == false { + if key.stringValue == "@text", node.text?.isEmpty == false { return true } return node.hasChild(for: key.stringValue) @@ -65,8 +69,9 @@ class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol // Get the child element matching the given key // Avoids initialization if all variables are nil. if let child = node.child(for: key.stringValue), - child.text?.isEmpty ?? true && - child.children?.isEmpty ?? true { + child.text?.isEmpty ?? true, + child.children?.isEmpty ?? true + { return true } @@ -115,11 +120,12 @@ class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol if type is XMLNamespaceCodable.Type { return try decoder.decode(node: node, as: T.self) } - + guard let child = node.child(for: key.stringValue) else { throw DecodingError.dataCorruptedError( forKey: key, in: self, - debugDescription: "Failed to decode \(type) value from key: \(key.stringValue)") + debugDescription: "Failed to decode \(type) value from key: \(key.stringValue)" + ) } return try decoder.decode(node: child, as: T.self) @@ -127,11 +133,11 @@ class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol // MARK: - - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + func nestedContainer(keyedBy _: NestedKey.Type, forKey _: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { fatalError() } - func nestedUnkeyedContainer(forKey key: Key) throws -> any UnkeyedDecodingContainer { + func nestedUnkeyedContainer(forKey _: Key) throws -> any UnkeyedDecodingContainer { fatalError() } @@ -139,7 +145,7 @@ class XMLKeyedDecodingContainer: KeyedDecodingContainerProtocol fatalError() } - func superDecoder(forKey key: Key) throws -> any Decoder { + func superDecoder(forKey _: Key) throws -> any Decoder { fatalError() } } diff --git a/Sources/XMLKit/XMLDecoder/XMLSingleValueDecodingContainer.swift b/Sources/XMLKit/XMLDecoder/XMLSingleValueDecodingContainer.swift index daf2705..1141c3b 100644 --- a/Sources/XMLKit/XMLDecoder/XMLSingleValueDecodingContainer.swift +++ b/Sources/XMLKit/XMLDecoder/XMLSingleValueDecodingContainer.swift @@ -1,50 +1,56 @@ // -// XMLSingleValueDecodingContainer.swift +// XMLSingleValueDecodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLSingleValueDecodingContainer: SingleValueDecodingContainer { - /// The XML decoder used for decoding the current element. - var decoder: _XMLDecoder - /// The current XML element being decoded. - var node: XMLNode - /// The coding path of the current decoding process. - var codingPath: [any CodingKey] { decoder.codingPath } + // MARK: Lifecycle init( decoder: _XMLDecoder, - node: XMLNode) { + node: XMLNode + ) { self.decoder = decoder self.node = node } + // MARK: Internal + + /// The XML decoder used for decoding the current element. + var decoder: _XMLDecoder + /// The current XML element being decoded. + var node: XMLNode + + /// The coding path of the current decoding process. + var codingPath: [any CodingKey] { decoder.codingPath } + // MARK: - func decodeNil() -> Bool { if - node.text?.isEmpty ?? true && - node.children?.isEmpty ?? true { + node.text?.isEmpty ?? true, + node.children?.isEmpty ?? true + { return true } return false diff --git a/Sources/XMLKit/XMLDecoder/XMLUnkeyedDecodingContainer.swift b/Sources/XMLKit/XMLDecoder/XMLUnkeyedDecodingContainer.swift index 859e677..a0d070c 100644 --- a/Sources/XMLKit/XMLDecoder/XMLUnkeyedDecodingContainer.swift +++ b/Sources/XMLKit/XMLDecoder/XMLUnkeyedDecodingContainer.swift @@ -1,44 +1,30 @@ // -// XMLUnkeyedDecodingContainer.swift +// XMLUnkeyedDecodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLUnkeyedDecodingContainer: UnkeyedDecodingContainer { - /// The XML decoder used for decoding the current node. - var decoder: _XMLDecoder - /// The XML nodes being decoded. - var nodes: [XMLNode] - /// The current XML node being decoded. - var node: XMLNode { nodes[currentIndex] } - /// The coding path of the current decoding process. - var codingPath: [CodingKey] { decoder.codingPath } - /// The number of nodes in the container, or `nil` if unknown. - var count: Int? { nodes.count } - /// A Boolean value indicating whether the container has reached the end. - var isAtEnd: Bool { currentIndex >= count ?? 0 } - /// The current index in the container's nodes. - var currentIndex: Int = 0 + // MARK: Lifecycle /// Initializes the container for decoding an unkeyed XML element. /// - Parameters: @@ -57,13 +43,31 @@ class XMLUnkeyedDecodingContainer: UnkeyedDecodingContainer { } } + // MARK: Internal + + /// The XML decoder used for decoding the current node. + var decoder: _XMLDecoder + /// The XML nodes being decoded. + var nodes: [XMLNode] + /// The current index in the container's nodes. + var currentIndex: Int = 0 + + /// The current XML node being decoded. + var node: XMLNode { nodes[currentIndex] } + /// The coding path of the current decoding process. + var codingPath: [CodingKey] { decoder.codingPath } + /// The number of nodes in the container, or `nil` if unknown. + var count: Int? { nodes.count } + /// A Boolean value indicating whether the container has reached the end. + var isAtEnd: Bool { currentIndex >= count ?? 0 } + // MARK: - Decode func decodeNil() throws -> Bool { fatalError() } - func decode(_ type: Bool.Type) throws -> Bool { + func decode(_: Bool.Type) throws -> Bool { fatalError() } @@ -111,7 +115,7 @@ class XMLUnkeyedDecodingContainer: UnkeyedDecodingContainer { // MARK: - - func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + func nestedContainer(keyedBy _: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { fatalError() } diff --git a/Sources/XMLKit/XMLDocument.swift b/Sources/XMLKit/XMLDocument.swift index cf32f8a..f07cb0e 100644 --- a/Sources/XMLKit/XMLDocument.swift +++ b/Sources/XMLKit/XMLDocument.swift @@ -1,33 +1,31 @@ // -// XMLDocument.swift +// XMLDocument.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Represents an XML document containing a root node. public class XMLDocument: Equatable, Hashable, Codable { - /// The root node of the document. - var root: XMLNode? + // MARK: Lifecycle /// Initializes a new document with an optional root node. /// - Parameter root: The root node of the document. @@ -35,6 +33,8 @@ public class XMLDocument: Equatable, Hashable, Codable { self.root = root } + // MARK: Public + // MARK: Equatable public static func == (lhs: XMLDocument, rhs: XMLDocument) -> Bool { @@ -60,6 +60,11 @@ public class XMLDocument: Equatable, Hashable, Codable { public func setRootAttribute(name: String, value: String) { root?.setAttribute(name: name, value: value) } + + // MARK: Internal + + /// The root node of the document. + var root: XMLNode? } // MARK: - XMLStringConvertible @@ -71,8 +76,11 @@ extension XMLDocument: XMLStringConvertible { /// - Returns: A string representation of the XML. public func toXMLString( formatted: Bool = false, - indentationLevel: Int = 1) -> String { - guard let root = root else { return "" } + indentationLevel _: Int = 1 + ) -> String { + guard let root else { + return "" + } // XML header let header = "" diff --git a/Sources/XMLKit/XMLDocumentConvertible.swift b/Sources/XMLKit/XMLDocumentConvertible.swift index 81f8e32..68b402d 100644 --- a/Sources/XMLKit/XMLDocumentConvertible.swift +++ b/Sources/XMLKit/XMLDocumentConvertible.swift @@ -1,26 +1,25 @@ // -// XMLDocumentConvertible.swift +// XMLDocumentConvertible.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/XMLKit/XMLElement.swift b/Sources/XMLKit/XMLElement.swift index 476b941..f532abc 100644 --- a/Sources/XMLKit/XMLElement.swift +++ b/Sources/XMLKit/XMLElement.swift @@ -1,80 +1,91 @@ // -// XMLElement.swift +// XMLElement.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// A generic text-based element with attributes. public struct XMLElement: Codable, Equatable, Hashable, Sendable { - /// The element's text. - public var text: String? - - /// The element's attributes. - public var attributes: Attributes? + // MARK: Lifecycle public init(text: String? = nil, attributes: Attributes? = nil) { self.text = text self.attributes = attributes } - private enum CodingKeys: String, CodingKey { - case text = "@text" - case attributes = "@attributes" - } - public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) text = try container.decodeIfPresent(String.self, forKey: .text) attributes = try container.decodeIfPresent(Attributes.self, forKey: .attributes) } + // MARK: Public + + /// The element's text. + public var text: String? + + /// The element's attributes. + public var attributes: Attributes? + public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(text, forKey: .text) try container.encodeIfPresent(attributes, forKey: .attributes) } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case text = "@text" + case attributes = "@attributes" + } } /// A generic element with only attributes. public struct XMLAttributesElement: Codable, Equatable, Hashable, Sendable { - /// The element's attributes. - public var attributes: Attributes? + // MARK: Lifecycle - public init(text: String? = nil, attributes: Attributes? = nil) { + public init(text _: String? = nil, attributes: Attributes? = nil) { self.attributes = attributes } - private enum CodingKeys: String, CodingKey { - case attributes = "@attributes" - } - public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) attributes = try container.decodeIfPresent(Attributes.self, forKey: .attributes) } + // MARK: Public + + /// The element's attributes. + public var attributes: Attributes? + public func encode(to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(attributes, forKey: .attributes) } + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case attributes = "@attributes" + } } diff --git a/Sources/XMLKit/XMLEncoder/XMLCodingKey.swift b/Sources/XMLKit/XMLEncoder/XMLCodingKey.swift index 896dbcf..831ea75 100644 --- a/Sources/XMLKit/XMLEncoder/XMLCodingKey.swift +++ b/Sources/XMLKit/XMLEncoder/XMLCodingKey.swift @@ -1,36 +1,32 @@ // -// XMLCodingKey.swift +// XMLCodingKey.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// A custom `CodingKey` implementation for encoding XML nodes. struct XMLCodingKey: CodingKey { - /// The string value of the coding key. - var stringValue: String - /// The integer value of the coding key, or `nil` if not applicable. - var intValue: Int? - + // MARK: Lifecycle + /// Initializes a new coding key with a string value. /// - Parameter stringValue: The string value for the key. init?(stringValue: String) { @@ -53,4 +49,11 @@ struct XMLCodingKey: CodingKey { self.stringValue = stringValue self.intValue = intValue } + + // MARK: Internal + + /// The string value of the coding key. + var stringValue: String + /// The integer value of the coding key, or `nil` if not applicable. + var intValue: Int? } diff --git a/Sources/XMLKit/XMLEncoder/XMLDateEncodingStrategy.swift b/Sources/XMLKit/XMLEncoder/XMLDateEncodingStrategy.swift index 6dd8340..4c3bad7 100644 --- a/Sources/XMLKit/XMLEncoder/XMLDateEncodingStrategy.swift +++ b/Sources/XMLKit/XMLEncoder/XMLDateEncodingStrategy.swift @@ -1,26 +1,25 @@ // -// XMLDateEncodingStrategy.swift +// XMLDateEncodingStrategy.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/XMLKit/XMLEncoder/XMLEncoder.swift b/Sources/XMLKit/XMLEncoder/XMLEncoder.swift index 607a1b2..788bd49 100644 --- a/Sources/XMLKit/XMLEncoder/XMLEncoder.swift +++ b/Sources/XMLKit/XMLEncoder/XMLEncoder.swift @@ -1,33 +1,36 @@ // -// XMLEncoder.swift +// XMLEncoder.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation public class XMLEncoder { + // MARK: Lifecycle + /// Creates a new instance of `XMLEncoder`. public init() {} + // MARK: Public + /// The strategy for encoding `Date` values into XML nodes. public var dateEncodingStrategy: XMLDateEncodingStrategy = .deferredToDate @@ -35,9 +38,9 @@ public class XMLEncoder { /// - Parameter value: The value to encode. /// - Returns: The encoded XML node. /// - Throws: An error if encoding fails. - public func encode(value: T) throws -> XMLKit.XMLDocument { - let key = XMLCodingKey(stringValue: "\(type(of: value))".lowercased(), intValue: nil) - let encoder = _XMLEncoder(codingPath: [key]) + public func encode(value: some Codable) throws -> XMLKit.XMLDocument { + let key: XMLCodingKey = .init(stringValue: "\(type(of: value))".lowercased(), intValue: nil) + let encoder: _XMLEncoder = .init(codingPath: [key]) encoder.dateEncodingStrategy = dateEncodingStrategy try value.encode(to: encoder) let rootNode = encoder.node! @@ -47,18 +50,7 @@ public class XMLEncoder { /// A custom encoder for encoding XML data using a stack-based approach. class _XMLEncoder: Encoder { - /// The stack used for managing XML nodes during encoding. - var stack: XMLStack = .init() - /// The current XML node being encoded, or `nil` if no node exists. - var node: XMLNode? { stack.top() } - /// The current key in the encoding path. - var currentKey: String { return codingPath.last!.stringValue } - /// The path of coding keys used to locate a value in the encoding process. - var codingPath: [any CodingKey] = [] - /// User-defined contextual information for the encoding process. - var userInfo: [CodingUserInfoKey: Any] = [:] - /// The strategy for encoding `Date` values into XML nodes. - var dateEncodingStrategy: XMLDateEncodingStrategy = .deferredToDate + // MARK: Lifecycle /// Initializes an XML encoder with an optional coding path. /// - Parameters: @@ -69,11 +61,27 @@ class _XMLEncoder: Encoder { userInfo = [:] } + // MARK: Internal + + /// The stack used for managing XML nodes during encoding. + var stack: XMLStack = .init() + /// The path of coding keys used to locate a value in the encoding process. + var codingPath: [any CodingKey] = [] + /// User-defined contextual information for the encoding process. + var userInfo: [CodingUserInfoKey: Any] = [:] + /// The strategy for encoding `Date` values into XML nodes. + var dateEncodingStrategy: XMLDateEncodingStrategy = .deferredToDate + + /// The current XML node being encoded, or `nil` if no node exists. + var node: XMLNode? { stack.top() } + /// The current key in the encoding path. + var currentKey: String { codingPath.last!.stringValue } + /// Returns a keyed encoding container for encoding XML nodes. /// - Parameter type: The type of the coding key. /// - Returns: A keyed encoding container. - func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { - let node = XMLNode(name: currentKey) + func container(keyedBy _: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { + let node: XMLNode = .init(name: currentKey) stack.push(node) return KeyedEncodingContainer(XMLKeyedEncodingContainer(node: node, encoder: self)) } @@ -88,7 +96,7 @@ class _XMLEncoder: Encoder { /// Returns a single-value encoding container for encoding a single XML node. /// - Returns: A single-value encoding container. func singleValueContainer() -> any SingleValueEncodingContainer { - return XMLSingleValueEncodingContainer(encoder: self, node: node!, codingPath: codingPath) + XMLSingleValueEncodingContainer(encoder: self, node: node!, codingPath: codingPath) } func box(_ date: Date) throws -> XMLNode { @@ -96,7 +104,7 @@ class _XMLEncoder: Encoder { case .deferredToDate: fatalError() case let .formatter(formatter): - return .init( + .init( name: currentKey, text: formatter.string(from: date) ) diff --git a/Sources/XMLKit/XMLEncoder/XMLKeyedEncodingContainer.swift b/Sources/XMLKit/XMLEncoder/XMLKeyedEncodingContainer.swift index b6a81e5..e7e48ae 100644 --- a/Sources/XMLKit/XMLEncoder/XMLKeyedEncodingContainer.swift +++ b/Sources/XMLKit/XMLEncoder/XMLKeyedEncodingContainer.swift @@ -1,36 +1,30 @@ // -// XMLKeyedEncodingContainer.swift +// XMLKeyedEncodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol { - /// The encoder used for encoding XML nodes. - let encoder: _XMLEncoder - /// The current XML node being encoded. - let node: XMLNode - /// The coding path of the current encoding process. - var codingPath: [any CodingKey] { encoder.codingPath } + // MARK: Lifecycle /// Initializes an encoding container for an XML node. /// - Parameters: @@ -41,7 +35,17 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol self.encoder = encoder } - func box(_ value: T, for key: Key) { + // MARK: Internal + + /// The encoder used for encoding XML nodes. + let encoder: _XMLEncoder + /// The current XML node being encoded. + let node: XMLNode + + /// The coding path of the current encoding process. + var codingPath: [any CodingKey] { encoder.codingPath } + + func box(_ value: some LosslessStringConvertible, for key: Key) { if key.stringValue == "@text" { node.text = "\(value)" return @@ -51,7 +55,7 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol // MARK: - - func encodeNil(forKey key: Key) throws { + func encodeNil(forKey _: Key) throws { fatalError() } @@ -81,7 +85,7 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol // MARK: - Type - func encode(_ value: T, forKey key: Key) throws where T: Encodable { + func encode(_ value: some Encodable, forKey key: Key) throws { encoder.codingPath.append(key) defer { self.encoder.codingPath.removeLast() } @@ -91,10 +95,10 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol let prefix = child.name let namespaceChildren = child.children - namespaceChildren?.forEach({ namespaceChild in + namespaceChildren?.forEach { namespaceChild in namespaceChild.prefix = prefix node.addChild(namespaceChild) - }) + } } else { node.addChild(child) @@ -104,11 +108,11 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol // MARK: - - func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer where NestedKey: CodingKey { + func nestedContainer(keyedBy _: NestedKey.Type, forKey _: Key) -> KeyedEncodingContainer where NestedKey: CodingKey { fatalError() } - func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { + func nestedUnkeyedContainer(forKey _: Key) -> UnkeyedEncodingContainer { fatalError() } @@ -116,7 +120,7 @@ class XMLKeyedEncodingContainer: KeyedEncodingContainerProtocol fatalError() } - func superEncoder(forKey key: Key) -> Encoder { + func superEncoder(forKey _: Key) -> Encoder { fatalError() } } diff --git a/Sources/XMLKit/XMLEncoder/XMLSingleValueEncodingContainer.swift b/Sources/XMLKit/XMLEncoder/XMLSingleValueEncodingContainer.swift index b131aee..e07e9f0 100644 --- a/Sources/XMLKit/XMLEncoder/XMLSingleValueEncodingContainer.swift +++ b/Sources/XMLKit/XMLEncoder/XMLSingleValueEncodingContainer.swift @@ -1,36 +1,30 @@ // -// XMLSingleValueEncodingContainer.swift +// XMLSingleValueEncodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLSingleValueEncodingContainer: SingleValueEncodingContainer { - /// The XML encoder used for encoding. - let encoder: _XMLEncoder - /// The XML node being encoded. - let node: XMLNode - /// The coding path of the current encoding process. - var codingPath: [any CodingKey] + // MARK: Lifecycle /// Initializes a container for encoding values to an XML node. /// - Parameters: @@ -43,7 +37,16 @@ class XMLSingleValueEncodingContainer: SingleValueEncodingContainer { self.codingPath = codingPath } - func box(_ value: T) -> XMLNode { + // MARK: Internal + + /// The XML encoder used for encoding. + let encoder: _XMLEncoder + /// The XML node being encoded. + let node: XMLNode + /// The coding path of the current encoding process. + var codingPath: [any CodingKey] + + func box(_ value: some LosslessStringConvertible) -> XMLNode { .init( name: encoder.currentKey, text: "\(value)" @@ -80,7 +83,7 @@ class XMLSingleValueEncodingContainer: SingleValueEncodingContainer { // MARK: - Encode Type - func encode(_ value: T) throws where T: Encodable { + func encode(_ value: some Encodable) throws { let some = try encoder.box(value) encoder.stack.push(some) } diff --git a/Sources/XMLKit/XMLEncoder/XMLUnkeyedEncodingContainer.swift b/Sources/XMLKit/XMLEncoder/XMLUnkeyedEncodingContainer.swift index 58ea7aa..8ad60c0 100644 --- a/Sources/XMLKit/XMLEncoder/XMLUnkeyedEncodingContainer.swift +++ b/Sources/XMLKit/XMLEncoder/XMLUnkeyedEncodingContainer.swift @@ -1,38 +1,30 @@ // -// XMLUnkeyedEncodingContainer.swift +// XMLUnkeyedEncodingContainer.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLUnkeyedEncodingContainer: UnkeyedEncodingContainer { - /// The XML encoder used for encoding values. - let encoder: _XMLEncoder - /// The XML node being encoded. - let node: XMLNode - /// The coding path of the current encoding process. - var codingPath: [CodingKey] { encoder.codingPath } - /// The number of children (encoded values) in the current node. - var count: Int = 0 + // MARK: Lifecycle /// Initializes a value encoding container for an XML node. /// - Parameters: @@ -43,16 +35,28 @@ class XMLUnkeyedEncodingContainer: UnkeyedEncodingContainer { self.encoder = encoder } + // MARK: Internal + + /// The XML encoder used for encoding values. + let encoder: _XMLEncoder + /// The XML node being encoded. + let node: XMLNode + /// The number of children (encoded values) in the current node. + var count: Int = 0 + + /// The coding path of the current encoding process. + var codingPath: [CodingKey] { encoder.codingPath } + /// Encodes a value and appends it as a child of the current node. /// - Parameter value: The value to encode, which must conform to /// `LosslessStringConvertible`. - func box(_ value: T) -> XMLNode { + func box(_ value: some LosslessStringConvertible) -> XMLNode { .init(name: encoder.currentKey, text: "\(value)") } // MARK: - - func encodeNil() throws { } + func encodeNil() throws {} func encode(_ value: Bool) throws { node.children?.append(box(value)); count += 1 } func encode(_ value: String) throws { node.children?.append(box(value)); count += 1 } @@ -80,10 +84,10 @@ class XMLUnkeyedEncodingContainer: UnkeyedEncodingContainer { // MARK: - Type - func encode(_ value: T) throws where T: Encodable { + func encode(_ value: some Encodable) throws { encoder.codingPath.append(XMLCodingKey(stringValue: encoder.currentKey, intValue: count)) defer { self.encoder.codingPath.removeLast() } - + let child = try encoder.box(value) if node !== child { node.addChild(child) @@ -93,7 +97,7 @@ class XMLUnkeyedEncodingContainer: UnkeyedEncodingContainer { // MARK: - - func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer where NestedKey: CodingKey { + func nestedContainer(keyedBy _: NestedKey.Type) -> KeyedEncodingContainer where NestedKey: CodingKey { fatalError() } diff --git a/Sources/XMLKit/XMLError.swift b/Sources/XMLKit/XMLError.swift index 6fbce9a..67779d5 100644 --- a/Sources/XMLKit/XMLError.swift +++ b/Sources/XMLKit/XMLError.swift @@ -1,26 +1,25 @@ // -// XMLError.swift +// XMLError.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation @@ -44,33 +43,33 @@ extension XMLError: LocalizedError { public var errorDescription: String? { switch self { case .notFound: - return "Feed not found." + "Feed not found." case .cdataDecoding: - return "Error decoding CDATA Block." + "Error decoding CDATA Block." case let .unexpected(reason): - return "Internal error: \(reason)." + "Internal error: \(reason)." } } public var failureReason: String? { switch self { case .notFound: - return "No recognizable feed was found in the parsed data." + "No recognizable feed was found in the parsed data." case let .cdataDecoding(element): - return "Failed to decode CDATA block to Unicode at element: \(element). Ensure the data is in UTF-8 format." + "Failed to decode CDATA block to Unicode at element: \(element). Ensure the data is in UTF-8 format." case let .unexpected(reason): - return "An internal error occurred that could not be resolved: \(reason)" + "An internal error occurred that could not be resolved: \(reason)" } } public var recoverySuggestion: String? { switch self { case .notFound: - return "Please provide a valid RSS, Atom, or JSON feed." + "Please provide a valid RSS, Atom, or JSON feed." case .cdataDecoding: - return "Verify that CDATA blocks are UTF-8 encoded." + "Verify that CDATA blocks are UTF-8 encoded." case .unexpected: - return "Consider submitting a detailed issue report on GitHub for assistance." + "Consider submitting a detailed issue report on GitHub for assistance." } } } @@ -81,15 +80,15 @@ extension XMLError: CustomNSError { /// An error's code for the specified case. public var errorCode: Int { switch self { - case .notFound: return -1000 - case .cdataDecoding: return -10001 - case .unexpected: return -90000 + case .notFound: -1000 + case .cdataDecoding: -10001 + case .unexpected: -90000 } } /// The error's userInfo dictionary for the specified case. public var errorUserInfo: [String: Any] { - return [ + [ NSLocalizedDescriptionKey: errorDescription ?? "", NSLocalizedFailureReasonErrorKey: failureReason ?? "", NSLocalizedRecoverySuggestionErrorKey: recoverySuggestion ?? "", @@ -98,12 +97,12 @@ extension XMLError: CustomNSError { /// The error's domain for the specified case. public static var errorDomain: String { - return "com.feedkit.error" + "com.feedkit.error" } /// The `NSError` from the specified case. public var error: NSError { - return NSError( + NSError( domain: XMLError.errorDomain, code: errorCode, userInfo: errorUserInfo diff --git a/Sources/XMLKit/XMLNamespaceCodable.swift b/Sources/XMLKit/XMLNamespaceCodable.swift index bace29b..55159dc 100644 --- a/Sources/XMLKit/XMLNamespaceCodable.swift +++ b/Sources/XMLKit/XMLNamespaceCodable.swift @@ -1,26 +1,25 @@ // -// XMLNamespaceCodable.swift +// XMLNamespaceCodable.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Sources/XMLKit/XMLNode.swift b/Sources/XMLKit/XMLNode.swift index e1951f5..8a17654 100644 --- a/Sources/XMLKit/XMLNode.swift +++ b/Sources/XMLKit/XMLNode.swift @@ -1,48 +1,31 @@ // -// XMLNode.swift +// XMLNode.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation /// Represents an node in the XML document. class XMLNode: Codable, Equatable, Hashable { - /// The parent node of this node. - weak var parent: XMLNode? - /// Is the `text` property xhtml - var isXhtml: Bool = false - /// The namespace prefix - var prefix: String? - /// The name of the node. - var name: String - /// The text of the node, if present. - var text: String? - /// The child nodes of this node. - var children: [XMLNode]? { - didSet { - // Update the parent reference for all children - children?.forEach { $0.parent = self } - } - } + // MARK: Lifecycle /// Initializes a new node. /// - Parameters: @@ -55,7 +38,8 @@ class XMLNode: Codable, Equatable, Hashable { name: String, text: String? = nil, isXhtml: Bool = false, - children: [XMLNode]? = nil) { + children: [XMLNode]? = nil + ) { self.prefix = prefix self.name = name self.text = text @@ -65,6 +49,18 @@ class XMLNode: Codable, Equatable, Hashable { self.children?.forEach { $0.parent = self } } + public required init(from decoder: any Decoder) throws { + let container: KeyedDecodingContainer = try decoder.container(keyedBy: XMLNode.CodingKeys.self) + + prefix = try container.decodeIfPresent(String.self, forKey: XMLNode.CodingKeys.prefix) + name = try container.decode(String.self, forKey: XMLNode.CodingKeys.name) + text = try container.decodeIfPresent(String.self, forKey: XMLNode.CodingKeys.text) + isXhtml = try container.decode(Bool.self, forKey: XMLNode.CodingKeys.isXhtml) + children = try container.decodeIfPresent([XMLNode].self, forKey: XMLNode.CodingKeys.children) + } + + // MARK: Public + // MARK: Equatable public static func == (lhs: XMLNode, rhs: XMLNode) -> Bool { @@ -73,7 +69,8 @@ class XMLNode: Codable, Equatable, Hashable { lhs.prefix != rhs.prefix || lhs.name != rhs.name || lhs.text != rhs.text || - lhs.isXhtml != rhs.isXhtml { + lhs.isXhtml != rhs.isXhtml + { return false } @@ -103,31 +100,11 @@ class XMLNode: Codable, Equatable, Hashable { hasher.combine(isXhtml) // Recursively hash the children - if let children = children { - hasher.combine(children.map { $0.hashValue }) + if let children { + hasher.combine(children.map(\.hashValue)) } } - // MARK: - Codable - - private enum CodingKeys: CodingKey { - case prefix - case name - case text - case isXhtml - case children - } - - public required init(from decoder: any Decoder) throws { - let container: KeyedDecodingContainer = try decoder.container(keyedBy: XMLNode.CodingKeys.self) - - prefix = try container.decodeIfPresent(String.self, forKey: XMLNode.CodingKeys.prefix) - name = try container.decode(String.self, forKey: XMLNode.CodingKeys.name) - text = try container.decodeIfPresent(String.self, forKey: XMLNode.CodingKeys.text) - isXhtml = try container.decode(Bool.self, forKey: XMLNode.CodingKeys.isXhtml) - children = try container.decodeIfPresent([XMLNode].self, forKey: XMLNode.CodingKeys.children) - } - public func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: XMLNode.CodingKeys.self) @@ -184,6 +161,39 @@ class XMLNode: Codable, Equatable, Hashable { )) } } + + // MARK: Internal + + /// The parent node of this node. + weak var parent: XMLNode? + /// Is the `text` property xhtml + var isXhtml: Bool = false + /// The namespace prefix + var prefix: String? + /// The name of the node. + var name: String + /// The text of the node, if present. + var text: String? + + /// The child nodes of this node. + var children: [XMLNode]? { + didSet { + // Update the parent reference for all children + children?.forEach { $0.parent = self } + } + } + + // MARK: Private + + // MARK: - Codable + + private enum CodingKeys: CodingKey { + case prefix + case name + case text + case isXhtml + case children + } } // MARK: - XMLStringConvertible @@ -196,7 +206,8 @@ extension XMLNode: XMLStringConvertible { /// - Returns: A string representation of the XML for the node. public func toXMLString( formatted: Bool = false, - indentationLevel: Int = 1) -> String { + indentationLevel: Int = 1 + ) -> String { let indent = formatted ? String(repeating: " ", count: indentationLevel) : "" // Skip processing nodes with the name "@attributes". diff --git a/Sources/XMLKit/XMLReader.swift b/Sources/XMLKit/XMLReader.swift index 30334c2..dbcdb34 100644 --- a/Sources/XMLKit/XMLReader.swift +++ b/Sources/XMLKit/XMLReader.swift @@ -1,26 +1,25 @@ // -// XMLReader.swift +// XMLReader.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation #if canImport(FoundationXML) @@ -28,6 +27,19 @@ import Foundation #endif class XMLReader: NSObject { + // MARK: Lifecycle + + /// Initializes the wrapper with XML data. + /// - Parameter data: The XML data to parse. + init(data: Data) { + parser = XMLParser(data: data) + stack = XMLStack() + super.init() + parser.delegate = self + } + + // MARK: Internal + /// The XML Parser. let parser: XMLParser /// A stack of `XMLNode` instances representing the current hierarchy @@ -44,15 +56,6 @@ class XMLReader: NSObject { /// Set to `true` when parsing is finished; otherwise, `false`. var isComplete = false - /// Initializes the wrapper with XML data. - /// - Parameter data: The XML data to parse. - init(data: Data) { - parser = XMLParser(data: data) - stack = XMLStack() - super.init() - parser.delegate = self - } - /// Parses the XML data and returns a `Result` indicating success or failure. /// - Returns: A `Result` with the parsed document on success, or an error. func read() -> Result { @@ -61,7 +64,8 @@ class XMLReader: NSObject { guard parser.parse(), error == nil, - let root = stack.pop() else { + let root = stack.pop() + else { let error = error ?? .unexpected(reason: "An unknown error occurred or the parsing operation aborted.") return .failure(error) } @@ -77,8 +81,12 @@ class XMLReader: NSObject { /// - Parameter string: The character data found in the XML. func map(_ string: String) { // Get the working element - guard let element = stack.top() else { return } - guard !string.isEmpty else { return } + guard let element = stack.top() else { + return + } + guard !string.isEmpty else { + return + } element.text = element.text?.appending(string) ?? string } } @@ -87,11 +95,12 @@ class XMLReader: NSObject { extension XMLReader: XMLParserDelegate { func parser( - _ parser: XMLParser, + _: XMLParser, didStartElement elementName: String, - namespaceURI: String?, - qualifiedName qName: String?, - attributes attributeDict: [String: String] = [:]) { + namespaceURI _: String?, + qualifiedName _: String?, + attributes attributeDict: [String: String] = [:] + ) { // Determine prefix and namespace var prefix: String? if elementName.contains(":") { @@ -117,7 +126,8 @@ extension XMLReader: XMLParserDelegate { ) } ), - ]) + ] + ) ) } else if let node = stack.top(), node.isXhtml { // If inside an XHTML element, treat the current start element as plain text. @@ -151,21 +161,24 @@ extension XMLReader: XMLParserDelegate { ) } ), - ]) + ] + ) ) } } } func parser( - _ parser: XMLParser, - foundCharacters string: String) { + _: XMLParser, + foundCharacters string: String + ) { map(string) } func parser( _ parser: XMLParser, - foundCDATA CDATABlock: Data) { + foundCDATA CDATABlock: Data + ) { // Attempts to decode a CDATA block to an encoding, ordered by priority for encoding in XMLReader.encodings { if let string = String(data: CDATABlock, encoding: encoding) { @@ -180,11 +193,14 @@ extension XMLReader: XMLParserDelegate { } func parser( - _ parser: XMLParser, + _: XMLParser, didEndElement elementName: String, - namespaceURI: String?, - qualifiedName qName: String?) { - guard let node = stack.top() else { return } + namespaceURI _: String?, + qualifiedName _: String? + ) { + guard let node = stack.top() else { + return + } // If exiting an XHTML element, close it as plain text. if node.isXhtml, node.name != elementName { @@ -206,7 +222,8 @@ extension XMLReader: XMLParserDelegate { } func parserDidEndDocument( - _ parser: XMLParser) { + _: XMLParser) + { #if DEBUG if !isComplete { print("Parsing ended without reaching the root path.") @@ -215,13 +232,16 @@ extension XMLReader: XMLParserDelegate { } func parser( - _ parser: XMLParser, - parseErrorOccurred parseError: Error) { + _: XMLParser, + parseErrorOccurred parseError: Error + ) { // Ignore errors that occur after a feed is successfully parsed. Some // real-world feeds contain junk such as "[]" after the XML segment; // just ignore this stuff. // https://github.com/nmdias/FeedKit/pull/53 - guard !isComplete, error == nil else { return } + guard !isComplete, error == nil else { + return + } error = .unexpected(reason: parseError.localizedDescription) } } diff --git a/Sources/XMLKit/XMLStack.swift b/Sources/XMLKit/XMLStack.swift index 8d123b4..12e1fb6 100644 --- a/Sources/XMLKit/XMLStack.swift +++ b/Sources/XMLKit/XMLStack.swift @@ -1,32 +1,35 @@ // -// XMLStack.swift +// XMLStack.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation class XMLStack { - /// The internal storage for the `XMLNode` stack. - private var stack: [XMLNode] = [] + // MARK: Internal + + /// The number of `XMLNode` instances in the stack. + var count: Int { + stack.count + } /// Pushes an `XMLNode` onto the stack. /// - Parameter node: The `XMLNode` to add to the stack. @@ -47,8 +50,8 @@ class XMLStack { stack.last } - /// The number of `XMLNode` instances in the stack. - var count: Int { - stack.count - } + // MARK: Private + + /// The internal storage for the `XMLNode` stack. + private var stack: [XMLNode] = [] } diff --git a/Sources/XMLKit/XMLStringConvertible.swift b/Sources/XMLKit/XMLStringConvertible.swift index 8cc084d..889ffa1 100644 --- a/Sources/XMLKit/XMLStringConvertible.swift +++ b/Sources/XMLKit/XMLStringConvertible.swift @@ -1,26 +1,25 @@ // -// XMLStringConvertible.swift +// XMLStringConvertible.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation diff --git a/Tests/FeedKitTests/FeedKitTestable.swift b/Tests/FeedKitTests/FeedKitTestable.swift index f34961c..15d5c90 100644 --- a/Tests/FeedKitTests/FeedKitTestable.swift +++ b/Tests/FeedKitTests/FeedKitTestable.swift @@ -1,26 +1,25 @@ // -// FeedKitTestable.swift +// FeedKitTestable.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import Testing @@ -95,10 +94,10 @@ extension FeedKitTestable { } } - func save(_ object: T, to directory: FileManager.SearchPathDirectory, as fileName: String) { + func save(_ object: some Codable, to directory: FileManager.SearchPathDirectory, as fileName: String) { do { // Convert object to JSON data - let encoder = JSONEncoder() + let encoder: JSONEncoder = .init() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let jsonData = try encoder.encode(object) diff --git a/Tests/FeedKitTests/Tests/AtomTests + Mocks.swift b/Tests/FeedKitTests/Tests/AtomTests + Mocks.swift index 25fe971..f129aba 100644 --- a/Tests/FeedKitTests/Tests/AtomTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/AtomTests + Mocks.swift @@ -1,26 +1,25 @@ // -// AtomTests + Mocks.swift +// AtomTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit diff --git a/Tests/FeedKitTests/Tests/AtomTests.swift b/Tests/FeedKitTests/Tests/AtomTests.swift index 8a98ce9..c3acdba 100644 --- a/Tests/FeedKitTests/Tests/AtomTests.swift +++ b/Tests/FeedKitTests/Tests/AtomTests.swift @@ -1,29 +1,27 @@ // -// AtomTests.swift +// AtomTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("Atom") diff --git a/Tests/FeedKitTests/Tests/BoolTests.swift b/Tests/FeedKitTests/Tests/BoolTests.swift index 37ccad1..15649f2 100644 --- a/Tests/FeedKitTests/Tests/BoolTests.swift +++ b/Tests/FeedKitTests/Tests/BoolTests.swift @@ -1,29 +1,27 @@ // -// BoolTests.swift +// BoolTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/ContentTests + Mocks.swift b/Tests/FeedKitTests/Tests/ContentTests + Mocks.swift index 032e2b2..e9bd3bc 100644 --- a/Tests/FeedKitTests/Tests/ContentTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/ContentTests + Mocks.swift @@ -1,26 +1,25 @@ // -// ContentTests + Mocks.swift +// ContentTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit @@ -33,7 +32,7 @@ extension ContentTests { content: .init( encoded: "

What a beautiful day!

" ) - ) + ), ] ) ) diff --git a/Tests/FeedKitTests/Tests/ContentTests.swift b/Tests/FeedKitTests/Tests/ContentTests.swift index 74ae8b5..d80547c 100644 --- a/Tests/FeedKitTests/Tests/ContentTests.swift +++ b/Tests/FeedKitTests/Tests/ContentTests.swift @@ -1,29 +1,27 @@ // -// ContentTests.swift +// ContentTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("Content") diff --git a/Tests/FeedKitTests/Tests/DateTests.swift b/Tests/FeedKitTests/Tests/DateTests.swift index 0e5a211..e6422e4 100644 --- a/Tests/FeedKitTests/Tests/DateTests.swift +++ b/Tests/FeedKitTests/Tests/DateTests.swift @@ -1,35 +1,33 @@ // -// DateTests.swift +// DateTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing @Suite("Date Formatters") struct DateTests { - var calendar: Calendar + // MARK: Lifecycle init() { calendar = Calendar(identifier: .gregorian) @@ -37,15 +35,19 @@ struct DateTests { calendar.timeZone = TimeZone(secondsFromGMT: 0)! } + // MARK: Internal + + var calendar: Calendar + // MARK: - RFC339 @Test func rfc3339() { // Given - let formatter = FeedDateFormatter(spec: .rfc3339) + let formatter: FeedDateFormatter = .init(spec: .rfc3339) let dateString = "2016-01-15T15:54:10-01:00" - let expected = DateComponents(year: 2016, month: 1, day: 15, hour: 16, minute: 54, second: 10) + let expected: DateComponents = .init(year: 2016, month: 1, day: 15, hour: 16, minute: 54, second: 10) // When let date = formatter.date(from: dateString) @@ -58,7 +60,7 @@ struct DateTests { @Test func rfc3339Spec() { // Given - let formatter = FeedDateFormatter(spec: .rfc3339) + let formatter: FeedDateFormatter = .init(spec: .rfc3339) let dateStrings = [ "2016-06-05T09:30:01Z", "2016-06-05T03:18:00Z", @@ -88,10 +90,10 @@ struct DateTests { @Test func rfc822() { // Given - let formatter = FeedDateFormatter(spec: .rfc822) + let formatter: FeedDateFormatter = .init(spec: .rfc822) let dateString = "Tue, 04 Feb 2014 22:03:45 Z" - let expected = DateComponents(year: 2014, month: 2, day: 4, hour: 22, minute: 3, second: 45) + let expected: DateComponents = .init(year: 2014, month: 2, day: 4, hour: 22, minute: 3, second: 45) // When let date = formatter.date(from: dateString) @@ -104,7 +106,7 @@ struct DateTests { @Test func rfc822Spec() { // Given - let formatter = FeedDateFormatter(spec: .rfc822) + let formatter: FeedDateFormatter = .init(spec: .rfc822) let dateStrings = [ "Tue, 04 Feb 2014 22:10:15 Z", "Sun, 05 Jun 2016 08:35:14 Z", @@ -138,10 +140,10 @@ struct DateTests { @Test func rfc8601() { // Given - let formatter = FeedDateFormatter(spec: .iso8601) + let formatter: FeedDateFormatter = .init(spec: .iso8601) let dateString = "1994-11-05T08:15:30-05:00" - let expected = DateComponents(year: 1994, month: 11, day: 5, hour: 13, minute: 15, second: 30) + let expected: DateComponents = .init(year: 1994, month: 11, day: 5, hour: 13, minute: 15, second: 30) // When let date = formatter.date(from: dateString) @@ -154,7 +156,7 @@ struct DateTests { @Test func rfc8601Spec() { // Given - let formatter = FeedDateFormatter(spec: .iso8601) + let formatter: FeedDateFormatter = .init(spec: .iso8601) let dateStrings = [ "1994-11-05T08:15:30-05:00", "1994-11-05T08:15:30.00-05:00", diff --git a/Tests/FeedKitTests/Tests/DublinCoreTests + Mocks.swift b/Tests/FeedKitTests/Tests/DublinCoreTests + Mocks.swift index 6ce7aa1..4f4b5fa 100644 --- a/Tests/FeedKitTests/Tests/DublinCoreTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/DublinCoreTests + Mocks.swift @@ -1,26 +1,25 @@ // -// DublinCoreTests + Mocks.swift +// DublinCoreTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit diff --git a/Tests/FeedKitTests/Tests/DublinCoreTests.swift b/Tests/FeedKitTests/Tests/DublinCoreTests.swift index 21c94ba..a05f77a 100644 --- a/Tests/FeedKitTests/Tests/DublinCoreTests.swift +++ b/Tests/FeedKitTests/Tests/DublinCoreTests.swift @@ -1,29 +1,27 @@ // -// DublinCoreTests.swift +// DublinCoreTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("Dublin Core") diff --git a/Tests/FeedKitTests/Tests/DurationTests.swift b/Tests/FeedKitTests/Tests/DurationTests.swift index 9d1e5b0..819d410 100644 --- a/Tests/FeedKitTests/Tests/DurationTests.swift +++ b/Tests/FeedKitTests/Tests/DurationTests.swift @@ -1,29 +1,27 @@ // -// DurationTests.swift +// DurationTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/FeedTests + Mocks.swift b/Tests/FeedKitTests/Tests/FeedTests + Mocks.swift index d1e5f33..3f38fab 100644 --- a/Tests/FeedKitTests/Tests/FeedTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/FeedTests + Mocks.swift @@ -1,26 +1,25 @@ // -// FeedTests + Mocks .swift +// FeedTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit diff --git a/Tests/FeedKitTests/Tests/FeedTests.swift b/Tests/FeedKitTests/Tests/FeedTests.swift index 7756d8d..3e47db6 100644 --- a/Tests/FeedKitTests/Tests/FeedTests.swift +++ b/Tests/FeedKitTests/Tests/FeedTests.swift @@ -1,29 +1,27 @@ // -// FeedTests.swift +// FeedTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/FeedTypeTests.swift b/Tests/FeedKitTests/Tests/FeedTypeTests.swift index 7940bd8..8aa5b14 100644 --- a/Tests/FeedKitTests/Tests/FeedTypeTests.swift +++ b/Tests/FeedKitTests/Tests/FeedTypeTests.swift @@ -1,29 +1,27 @@ // -// FeedTypeTests.swift +// FeedTypeTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("FeedType") diff --git a/Tests/FeedKitTests/Tests/GMLPositionTests.swift b/Tests/FeedKitTests/Tests/GMLPositionTests.swift index bb14b87..6a6a82e 100644 --- a/Tests/FeedKitTests/Tests/GMLPositionTests.swift +++ b/Tests/FeedKitTests/Tests/GMLPositionTests.swift @@ -1,29 +1,27 @@ // -// MediaTagsTests.swift +// GMLPositionTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/JSONTests + Mocks.swift b/Tests/FeedKitTests/Tests/JSONTests + Mocks.swift index cf54e99..d1c3fa1 100644 --- a/Tests/FeedKitTests/Tests/JSONTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/JSONTests + Mocks.swift @@ -1,26 +1,25 @@ // -// JSONTests + Mocks.swift +// JSONTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit @@ -29,10 +28,10 @@ extension JSONTests { .init( title: "Title", homePageURL: "https://example.org/", - feedUrl: "https://example.org/feed.json?p=1", + feedURL: "https://example.org/feed.json?p=1", description: "Description", userComment: "User comment", - nextUrl: "https://example.org/feed.json?p=2", + nextURL: "https://example.org/feed.json?p=2", icon: "https://example.org/icon.jpg", favicon: "https://example.org/favicon.ico", author: .init( @@ -55,7 +54,7 @@ extension JSONTests { .init( id: "http://therecord.co/chris-parrish", url: "http://therecord.co/chris-parrish", - externalUrl: "http://external.com/example", + externalURL: "http://external.com/example", title: "Special #1 - Chris Parrish", contentText: "Chris has worked at Adobe and as a founder of Rogue Sheep, which won an Apple Design Award for Postage. Chris's new company is Aged & Distilled with Guy English - which shipped Napkin, a Mac app for visual collaboration. Chris is also the co-host of The Record. He lives on Bainbridge Island, a quick ferry ride from Seattle.", contentHtml: "Chris has worked at
Adobe and as a founder of Rogue Sheep, which won an Apple Design Award for Postage. Chris's new company is Aged & Distilled with Guy English - which shipped Napkin, a Mac app for visual collaboration. Chris is also the co-host of The Record. He lives on Bainbridge Island, a quick ferry ride from Seattle.", @@ -78,14 +77,14 @@ extension JSONTests { url: "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish-128.m4a", mimeType: "audio/x-m4a", title: "128Kb's version", - sizeInBytes: 63207998, + sizeInBytes: 63_207_998, durationInSeconds: 6629 ), .init( url: "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish-256.m4a", mimeType: "audio/x-m4a", title: "256Kb's version", - sizeInBytes: 89970236, + sizeInBytes: 89_970_236, durationInSeconds: 6629 ), ] @@ -93,7 +92,7 @@ extension JSONTests { .init( id: "1", url: "https://example.org/initial-post", - externalUrl: nil, + externalURL: nil, title: nil, contentText: nil, contentHtml: "

Hello, world!

", diff --git a/Tests/FeedKitTests/Tests/JSONTests.swift b/Tests/FeedKitTests/Tests/JSONTests.swift index d55dad7..c020d46 100644 --- a/Tests/FeedKitTests/Tests/JSONTests.swift +++ b/Tests/FeedKitTests/Tests/JSONTests.swift @@ -1,29 +1,27 @@ // -// JSONTests.swift +// JSONTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/KeywordsTests.swift b/Tests/FeedKitTests/Tests/KeywordsTests.swift index 7508f3a..187b1ad 100644 --- a/Tests/FeedKitTests/Tests/KeywordsTests.swift +++ b/Tests/FeedKitTests/Tests/KeywordsTests.swift @@ -1,29 +1,27 @@ // -// KeywordsTests.swift +// KeywordsTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/MediaTagsTests.swift b/Tests/FeedKitTests/Tests/MediaTagsTests.swift index efaf0ac..95ec391 100644 --- a/Tests/FeedKitTests/Tests/MediaTagsTests.swift +++ b/Tests/FeedKitTests/Tests/MediaTagsTests.swift @@ -1,29 +1,27 @@ // -// MediaTagsTests.swift +// MediaTagsTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Foundation import Testing diff --git a/Tests/FeedKitTests/Tests/MediaTests + Mocks.swift b/Tests/FeedKitTests/Tests/MediaTests + Mocks.swift index 45c9a0a..18a7c0e 100644 --- a/Tests/FeedKitTests/Tests/MediaTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/MediaTests + Mocks.swift @@ -1,28 +1,28 @@ // -// MediaTests + Mocks.swift +// MediaTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit + extension MediaTests { var mock: RSSFeed { var media: Media = .init() @@ -125,7 +125,7 @@ extension MediaTests { .init( attributes: .init( url: "http://www.foo.com/video.mov", - fileSize: 12216320, + fileSize: 12_216_320, type: "video/quicktime", medium: "video", isDefault: true, @@ -149,7 +149,7 @@ extension MediaTests { .init( attributes: .init( url: "http://www.foo.com/movie.mov", - fileSize: 12216320, + fileSize: 12_216_320, type: "video/quicktime", medium: nil, isDefault: nil, @@ -299,10 +299,10 @@ extension MediaTests { attributes: .init( name: "flashVars" ) - ) + ), ] ) - + media.status = .init( text: nil, attributes: .init( @@ -359,7 +359,7 @@ extension MediaTests { href: "http://www.licensehost.com/license" ) ) - + media.location = .init( attributes: .init( description: "My house", @@ -372,7 +372,7 @@ extension MediaTests { ) ) ) - + media.peerLink = .init( text: nil, attributes: .init( @@ -380,7 +380,7 @@ extension MediaTests { href: "http://www.foo.org/sampleFile.torrent" ) ) - + media.prices = [ .init( text: nil, @@ -390,16 +390,16 @@ extension MediaTests { info: "http://www.dummy.jp/package_info.html", currency: "EUR" ) - ) + ), ] - + media.responses = .init( responses: [ "http://www.response1.com", - "http://www.response2.com" + "http://www.response2.com", ] ) - + media.restriction = .init( text: "au us", attributes: .init( @@ -407,7 +407,7 @@ extension MediaTests { type: "country" ) ) - + media.scenes = .init( scenes: [ .init( diff --git a/Tests/FeedKitTests/Tests/MediaTests.swift b/Tests/FeedKitTests/Tests/MediaTests.swift index e8fd52c..944af1a 100644 --- a/Tests/FeedKitTests/Tests/MediaTests.swift +++ b/Tests/FeedKitTests/Tests/MediaTests.swift @@ -1,29 +1,27 @@ // -// MediaTests.swift +// MediaTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("Media") diff --git a/Tests/FeedKitTests/Tests/RSSAtomTests + Mocks.swift b/Tests/FeedKitTests/Tests/RSSAtomTests + Mocks.swift index 77dac82..5f41620 100644 --- a/Tests/FeedKitTests/Tests/RSSAtomTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/RSSAtomTests + Mocks.swift @@ -1,26 +1,25 @@ // -// YouTubeTests + Mocks.swift +// RSSAtomTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit diff --git a/Tests/FeedKitTests/Tests/RSSAtomTests.swift b/Tests/FeedKitTests/Tests/RSSAtomTests.swift index a70cb90..34fb467 100644 --- a/Tests/FeedKitTests/Tests/RSSAtomTests.swift +++ b/Tests/FeedKitTests/Tests/RSSAtomTests.swift @@ -1,29 +1,27 @@ // -// RSSAtomTests.swift +// RSSAtomTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("RSS Atom") diff --git a/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift b/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift index 0b3d50e..12a842c 100644 --- a/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/RSSTests + Mocks.swift @@ -1,26 +1,25 @@ // -// RSSTests + Mocks.swift +// RSSTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit @@ -110,7 +109,7 @@ extension RSSTests { enclosure: .init( attributes: .init( url: "http://dallas.example.com/joebob_050689.mp3", - length: 24986239, + length: 24_986_239, type: "audio/mpeg" ) ), @@ -148,7 +147,7 @@ extension RSSTests { enclosure: .init( attributes: .init( url: "http://dallas.example.com/joebob_050689.mp3", - length: 24986239, + length: 24_986_239, type: "audio/mpeg" ) ), diff --git a/Tests/FeedKitTests/Tests/RSSTests.swift b/Tests/FeedKitTests/Tests/RSSTests.swift index 40ac620..3e7eb87 100644 --- a/Tests/FeedKitTests/Tests/RSSTests.swift +++ b/Tests/FeedKitTests/Tests/RSSTests.swift @@ -1,29 +1,27 @@ // -// RSSTests.swift +// RSSTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("RSS") diff --git a/Tests/FeedKitTests/Tests/SyndicationTests + Mocks.swift b/Tests/FeedKitTests/Tests/SyndicationTests + Mocks.swift index b6d3523..f2e16e9 100644 --- a/Tests/FeedKitTests/Tests/SyndicationTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/SyndicationTests + Mocks.swift @@ -1,26 +1,25 @@ // -// SyndicationTests + Mocks.swift +// SyndicationTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit diff --git a/Tests/FeedKitTests/Tests/SyndicationTests.swift b/Tests/FeedKitTests/Tests/SyndicationTests.swift index 41ce8d6..f53c68f 100644 --- a/Tests/FeedKitTests/Tests/SyndicationTests.swift +++ b/Tests/FeedKitTests/Tests/SyndicationTests.swift @@ -1,29 +1,27 @@ // -// SyndicationTests.swift +// SyndicationTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("Syndication") diff --git a/Tests/FeedKitTests/Tests/YouTubeTests + Mocks.swift b/Tests/FeedKitTests/Tests/YouTubeTests + Mocks.swift index 6c06989..e36d832 100644 --- a/Tests/FeedKitTests/Tests/YouTubeTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/YouTubeTests + Mocks.swift @@ -1,26 +1,25 @@ // -// YouTubeTests + Mocks.swift +// YouTubeTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit @@ -39,7 +38,7 @@ extension YouTubeTests { channelID: "UCE_M8A5yxnLfW0KghEeajjw", videoID: "j1HGOY32s2Y" ) - ) + ), ] ) } diff --git a/Tests/FeedKitTests/Tests/YouTubeTests.swift b/Tests/FeedKitTests/Tests/YouTubeTests.swift index bb43f39..09e2622 100644 --- a/Tests/FeedKitTests/Tests/YouTubeTests.swift +++ b/Tests/FeedKitTests/Tests/YouTubeTests.swift @@ -1,29 +1,27 @@ // -// YouTubeTests.swift +// YouTubeTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("YouTube") diff --git a/Tests/FeedKitTests/Tests/iTunesTests + Mocks.swift b/Tests/FeedKitTests/Tests/iTunesTests + Mocks.swift index 066d61c..b20fb3c 100644 --- a/Tests/FeedKitTests/Tests/iTunesTests + Mocks.swift +++ b/Tests/FeedKitTests/Tests/iTunesTests + Mocks.swift @@ -1,26 +1,25 @@ // -// iTunesTests + Mocks.swift +// iTunesTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit @@ -29,7 +28,7 @@ extension iTunesTests { .init( channel: .init( items: [ - .init( + .init( iTunes: .init( author: "Dan Carlin", block: "No", @@ -72,7 +71,7 @@ extension iTunesTests { text: nil, attributes: .init( href: "http://www.dancarlin.com/graphics/DC_HH_iTunes.jpg" - ) + ) ), explicit: "No", complete: "No", diff --git a/Tests/FeedKitTests/Tests/iTunesTests.swift b/Tests/FeedKitTests/Tests/iTunesTests.swift index e32a64a..c8a6aa3 100644 --- a/Tests/FeedKitTests/Tests/iTunesTests.swift +++ b/Tests/FeedKitTests/Tests/iTunesTests.swift @@ -1,29 +1,27 @@ // -// iTunesTests.swift +// iTunesTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import FeedKit - import Testing @Suite("iTunes") diff --git a/Tests/XMLKitTests/Tests/SampleTests + Mocks.swift b/Tests/XMLKitTests/Tests/SampleTests + Mocks.swift index 5f95861..b9f920f 100644 --- a/Tests/XMLKitTests/Tests/SampleTests + Mocks.swift +++ b/Tests/XMLKitTests/Tests/SampleTests + Mocks.swift @@ -1,52 +1,43 @@ // -// SampleTests + Mocks.swift +// SampleTests + Mocks.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. @testable import XMLKit struct Sample: Codable, Equatable { - var attributes: Attributes? - var header: Header? - var content: Content? - var footer: Footer? - struct Attributes: Codable, Equatable { var xmlns: String? } struct Header: Codable, Equatable { - var title: Title? - var description: String? - var version: String? - var keywords: Keywords? - var namespace: Namespace? + // MARK: Lifecycle init( title: Title? = nil, description: String? = nil, version: String? = nil, keywords: Keywords? = nil, - namespace: Namespace? = nil) { + namespace: Namespace? = nil + ) { self.title = title self.description = description self.version = version @@ -54,22 +45,20 @@ struct Sample: Codable, Equatable { self.namespace = namespace } - private enum CodingKeys: String, CodingKey { - case title - case description - case version - case keywords - case namespace = "ns" - } + // MARK: Internal struct Title: Codable, Equatable { - var text: String? - var attributes: Attributes? + // MARK: Internal struct Attributes: Codable, Equatable { var type: String? } + var text: String? + var attributes: Attributes? + + // MARK: Private + private enum CodingKeys: String, CodingKey { case text = "@text" case attributes = "@attributes" @@ -81,40 +70,47 @@ struct Sample: Codable, Equatable { } struct Namespace: Codable, Equatable, XMLNamespaceCodable { + // MARK: Internal + var title: String? var description: String? + // MARK: Private + private enum CodingKeys: String, CodingKey { case title = "ns:title" case description = "ns:description" } } + + var title: Title? + var description: String? + var version: String? + var keywords: Keywords? + var namespace: Namespace? + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case title + case description + case version + case keywords + case namespace = "ns" + } } struct Content: Codable, Equatable { - var item: [Item] - struct Item: Codable, Equatable { - var name: String? - var description: String? - var precision: Double? - var details: Details? - var xhtml: Xhtml? - - private enum CodingKeys: String, CodingKey { - case name - case description - case precision - case details - case xhtml - } + // MARK: Lifecycle init( name: String? = nil, description: String? = nil, precision: Double? = nil, details: Details? = nil, - xhtml: Xhtml? = nil) { + xhtml: Xhtml? = nil + ) { self.name = name self.description = description self.precision = precision @@ -122,29 +118,55 @@ struct Sample: Codable, Equatable { self.xhtml = xhtml } + // MARK: Internal + struct Details: Codable, Equatable { var detail: [String]? } struct Xhtml: Codable, Equatable { - var attributes: XhtmlAttributes? - var text: String? + // MARK: Lifecycle init(attributes: XhtmlAttributes, text: String) { self.attributes = attributes self.text = text } + // MARK: Internal + + struct XhtmlAttributes: Codable, Equatable { + var type: String? + } + + var attributes: XhtmlAttributes? + var text: String? + + // MARK: Private + private enum CodingKeys: String, CodingKey { case attributes = "@attributes" case text = "@text" } + } - struct XhtmlAttributes: Codable, Equatable { - var type: String? - } + var name: String? + var description: String? + var precision: Double? + var details: Details? + var xhtml: Xhtml? + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case name + case description + case precision + case details + case xhtml } } + + var item: [Item] } struct Footer: Codable, Equatable { @@ -152,6 +174,11 @@ struct Sample: Codable, Equatable { var created: String? var revision: Int? } + + var attributes: Attributes? + var header: Header? + var content: Content? + var footer: Footer? } extension Sample { @@ -161,24 +188,23 @@ extension Sample { case content case footer } - + init(from decoder: any Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: Sample.CodingKeys.self) - - self.attributes = try container.decodeIfPresent(Sample.Attributes.self, forKey: Sample.CodingKeys.attributes) - self.header = try container.decodeIfPresent(Sample.Header.self, forKey: Sample.CodingKeys.header) - self.content = try container.decodeIfPresent(Sample.Content.self, forKey: Sample.CodingKeys.content) - self.footer = try container.decodeIfPresent(Sample.Footer.self, forKey: Sample.CodingKeys.footer) - + + attributes = try container.decodeIfPresent(Sample.Attributes.self, forKey: Sample.CodingKeys.attributes) + header = try container.decodeIfPresent(Sample.Header.self, forKey: Sample.CodingKeys.header) + content = try container.decodeIfPresent(Sample.Content.self, forKey: Sample.CodingKeys.content) + footer = try container.decodeIfPresent(Sample.Footer.self, forKey: Sample.CodingKeys.footer) } - + func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: Sample.CodingKeys.self) - - try container.encodeIfPresent(self.attributes, forKey: Sample.CodingKeys.attributes) - try container.encodeIfPresent(self.header, forKey: Sample.CodingKeys.header) - try container.encodeIfPresent(self.content, forKey: Sample.CodingKeys.content) - try container.encodeIfPresent(self.footer, forKey: Sample.CodingKeys.footer) + + try container.encodeIfPresent(attributes, forKey: Sample.CodingKeys.attributes) + try container.encodeIfPresent(header, forKey: Sample.CodingKeys.header) + try container.encodeIfPresent(content, forKey: Sample.CodingKeys.content) + try container.encodeIfPresent(footer, forKey: Sample.CodingKeys.footer) } } @@ -186,18 +212,17 @@ extension Sample.Attributes { private enum CodingKeys: String, CodingKey { case xmlns = "xmlns:ns" } - + init(from decoder: any Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: Sample.Attributes.CodingKeys.self) - - self.xmlns = try container.decodeIfPresent(String.self, forKey: Sample.Attributes.CodingKeys.xmlns) - + + xmlns = try container.decodeIfPresent(String.self, forKey: Sample.Attributes.CodingKeys.xmlns) } - + func encode(to encoder: any Encoder) throws { var container: KeyedEncodingContainer = encoder.container(keyedBy: Sample.Attributes.CodingKeys.self) - - try container.encodeIfPresent(self.xmlns, forKey: Sample.Attributes.CodingKeys.xmlns) + + try container.encodeIfPresent(xmlns, forKey: Sample.Attributes.CodingKeys.xmlns) } } @@ -289,7 +314,7 @@ extension SampleTests { .init( name: "xmlns:ns", text: "http://example.ns/namespace" - ) + ), ] ), .init( diff --git a/Tests/XMLKitTests/Tests/SampleTests.swift b/Tests/XMLKitTests/Tests/SampleTests.swift index 215f31b..831afca 100644 --- a/Tests/XMLKitTests/Tests/SampleTests.swift +++ b/Tests/XMLKitTests/Tests/SampleTests.swift @@ -1,30 +1,28 @@ // -// SampleTests.swift +// SampleTests.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import XMLKit +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Testing +@testable import XMLKit @Suite("Sample") struct SampleTests: XMLKitTestable { @@ -32,7 +30,7 @@ struct SampleTests: XMLKitTestable { func xmlReader() throws { // Given let data = data(resource: "Sample", withExtension: "xml") - let reader = XMLReader(data: data) + let reader: XMLReader = .init(data: data) let expected: XMLNode = nodeMock // When @@ -46,8 +44,8 @@ struct SampleTests: XMLKitTestable { func xmlString() throws { // Given let data = data(resource: "Sample", withExtension: "xml") - let expected = String(decoding: data, as: Unicode.UTF8.self) - let document = XMLDocument(root: nodeMock) + let expected: String = .init(decoding: data, as: Unicode.UTF8.self) + let document: XMLDocument = .init(root: nodeMock) // When let actual = document.toXMLString(formatted: true) @@ -59,7 +57,7 @@ struct SampleTests: XMLKitTestable { @Test("Encode Node -> Model") func xmlDecoder() throws { // Given - let decoder = XMLDecoder() + let decoder: XMLDecoder = .init() let expected: Sample = sampleMock // When @@ -72,8 +70,8 @@ struct SampleTests: XMLKitTestable { @Test("Encode Model -> Node -> Model") func xmlEncoderDecoder() throws { // Given - let encoder = XMLEncoder() - let decoder = XMLDecoder() + let encoder: XMLEncoder = .init() + let decoder: XMLDecoder = .init() let expected: Sample = sampleMock // When diff --git a/Tests/XMLKitTests/XMLKitTestable.swift b/Tests/XMLKitTests/XMLKitTestable.swift index 0a7128b..3a2e693 100644 --- a/Tests/XMLKitTests/XMLKitTestable.swift +++ b/Tests/XMLKitTests/XMLKitTestable.swift @@ -1,26 +1,25 @@ // -// XMLKitTestable.swift +// XMLKitTestable.swift // -// Copyright (c) 2016 - 2025 Nuno Dias +// Copyright (c) 2016 - 2025 Nuno Dias // -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: // -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. import Foundation import Testing @@ -95,10 +94,10 @@ extension XMLKitTestable { } } - func save(_ object: T, to directory: FileManager.SearchPathDirectory, as fileName: String) { + func save(_ object: some Codable, to directory: FileManager.SearchPathDirectory, as fileName: String) { do { // Convert object to JSON data - let encoder = JSONEncoder() + let encoder: JSONEncoder = .init() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let jsonData = try encoder.encode(object)