swift-libs/Sources/Core/Property Wrappers/LossyCodableList.swift
Javier Cicchelli 5286f72f05 [Bugifx] Lossy codable list documentation (#20)
This PR contains the work done to amend some documentation in the `LossyCodableList` struct.

Co-authored-by: Javier Cicchelli <javier@rock-n-code.com>
Reviewed-on: #20
2023-05-07 20:01:05 +00:00

92 lines
2.6 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftLibs open source project
//
// Copyright (c) 2023 Röck+Cöde VoF. and the SwiftLibs project authors
// Licensed under the EUPL 1.2 or later.
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftLibs project authors
//
//===----------------------------------------------------------------------===//
/// This struct (that could also be used as a property wrapper as well) provides a generic type that acts as a thin wrapper around an array of `Elements` instances to allow a lossy decoding and or encoding process.
///
/// This implementation is heavily influenced by this [article](https://www.swiftbysundell.com/articles/ignoring-invalid-json-elements-codable/).
@propertyWrapper
public struct LossyCodableList<Element> {
// MARK: Properties
private var elements: [Element]
/// Provides read/write access to the array of `Element` instances.
public var wrappedValue: [Element] {
get { elements }
set { elements = newValue }
}
// MARK: Initialisers
/// Initialises this struct.
public init() {
self.elements = []
}
}
// MARK: - Decodable
extension LossyCodableList: Decodable where Element: Decodable {
// MARK: Initialisers
/// Initialises the struct with a lossy decoder.
/// - Parameter decoder: The decoder to use for the lossy decoder process.
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let wrappers = try container.decode([ElementWrapper].self)
self.elements = wrappers.compactMap(\.element)
}
}
// MARK: - Encodable
extension LossyCodableList: Encodable where Element: Encodable {
// MARK: Functions
/// Encodes an array of `Element` instances loosely.
/// - Parameter encoder: The encoder to use for the lossy encoding process.
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
elements.forEach { element in
try? container.encode(element)
}
}
}
// MARK: - Structs
private extension LossyCodableList where Element: Decodable {
struct ElementWrapper: Decodable {
// MARK: Properties
var element: Element?
// MARK: Initialisers
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.element = try? container.decode(Element.self)
}
}
}