-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for partially decoding arrays (#107)
* save point - start adding support for lossy array decoding * clean up some documentation, add sendable conformance to retry config * Change concurrency checking to complete * dont force unwrap final resource when auto decoding lossy array * remove convenience extension that wasn't working properly * Move FailableDecodable into LossyArray, rework LossyArray a ltitle for easier extension * switch array decoding to be request-level this is kind of a save point - doesnt work with smart unwrap yet * add lossy decoding for smart unwraps * update changelog - bump version to 2.1.0
- Loading branch information
1 parent
5ce356e
commit c6059d0
Showing
12 changed files
with
206 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// ArrayDecodeStrategy.swift | ||
// Netable | ||
// | ||
// Created by Brendan on 2022-12-06. | ||
// Copyright © 2022 Steamclock Software. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// Strategy to use when decoding top-level arrays of values | ||
/// By default, if you try to decode an array objects and one of the objects fails to decode, the entire array fails to decode. | ||
/// Instead, this allows you to partially decode arrays and only return the well-formed elements. | ||
/// For lossy decoding nested arrays, we recommend checking out [Better Codable](https://github.com/marksands/BetterCodable). | ||
public enum ArrayDecodeStrategy { | ||
/// If any element of the array fails to decode, the whole array fails. | ||
case standard | ||
/// Decode the array, omitting any elements that fail to decode. | ||
case lossy | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// | ||
// LossyArray.swift | ||
// Netable | ||
// | ||
// Created by Brendan on 2022-11-30. | ||
// Copyright © 2022 Steamclock Software. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// Adapted from https://stackoverflow.com/a/46369152 | ||
|
||
/// Array container that allows for partial decoding of elements. | ||
/// If an element of the array fails to decode, it will be omitted rather than the rest of the array failing to decode. | ||
public struct LossyArray<Element> { | ||
/// All elements of the array that decoded successfully. | ||
public var elements: [Element] | ||
|
||
public init(elements: [Element]) { | ||
self.elements = elements | ||
} | ||
} | ||
|
||
extension LossyArray: Decodable where Element: Decodable { | ||
/// Decode non-optional item into an optional element. | ||
public struct FailableDecodable<Element: Decodable>: Decodable { | ||
public var element: Element? | ||
|
||
/// Decode an element and set it to `nil` if decoding fails. | ||
public init(from decoder: Decoder) throws { | ||
let container = try decoder.singleValueContainer() | ||
element = try? container.decode(Element.self) | ||
} | ||
} | ||
|
||
/// Attempt to decode the contents of an array, omitting any results that fail to decode. | ||
public init(from decoder: Decoder) throws { | ||
var elements = [Element?]() | ||
var container = try decoder.unkeyedContainer() | ||
while !container.isAtEnd { | ||
let item = try container.decode(FailableDecodable<Element>.self).element | ||
elements.append(item) | ||
} | ||
self.elements = elements.compactMap { $0 } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.