added property wrapper for default values

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2022-05-11 09:17:39 -05:00
parent 9bb90b2153
commit 9e9421f66a
2 changed files with 91 additions and 0 deletions

View File

@ -159,6 +159,7 @@
D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DEDCBA23C65BC300C44CC4 /* Percent.swift */; };
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */; };
EA09CD62282ACDDB00A7835F /* Decoder+UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA09CD61282ACDDB00A7835F /* Decoder+UserInfo.swift */; };
EA09CD99282BF83600A7835F /* DecodableDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA09CD98282BF83600A7835F /* DecodableDefault.swift */; };
EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */; };
/* End PBXBuildFile section */
@ -309,6 +310,7 @@
D2DEDCBA23C65BC300C44CC4 /* Percent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Percent.swift; sourceTree = "<group>"; };
D2E1FAD82260C3E400AEFD8C /* DelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateObject.swift; sourceTree = "<group>"; };
EA09CD61282ACDDB00A7835F /* Decoder+UserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Decoder+UserInfo.swift"; sourceTree = "<group>"; };
EA09CD98282BF83600A7835F /* DecodableDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecodableDefault.swift; sourceTree = "<group>"; };
EA3B264B25FC0B7600008074 /* ModelHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelHandlerProtocol.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -688,6 +690,7 @@
D2DEDCB623C63F3B00C44CC4 /* Clamping.swift */,
D2DEDCB823C6400600C44CC4 /* UnitInterval.swift */,
D2DEDCBA23C65BC300C44CC4 /* Percent.swift */,
EA09CD98282BF83600A7835F /* DecodableDefault.swift */,
);
path = PropertyWrappers;
sourceTree = "<group>";
@ -915,6 +918,7 @@
AF43A70A1FC4F415008E9347 /* MVMCoreCache.m in Sources */,
AF43A6FF1FBE3252008E9347 /* Reachability.m in Sources */,
EA09CD62282ACDDB00A7835F /* Decoder+UserInfo.swift in Sources */,
EA09CD99282BF83600A7835F /* DecodableDefault.swift in Sources */,
01C851D123CF97FE0021F976 /* ActionBackModel.swift in Sources */,
D27073D125BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift in Sources */,
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,

View File

@ -0,0 +1,87 @@
//
// DecoderDefault.swift
// MVMCore
//
// Created by Matt Bruce on 5/11/22.
// Copyright © 2022 myverizon. All rights reserved.
//
import Foundation
/// https://www.swiftbysundell.com/tips/default-decoding-values/
/// This code is used for Decodable objects that allow Default Values to be added.
public protocol DecodableDefaultSource {
associatedtype Value: Decodable
static var defaultValue: Value { get }
}
public enum DecodableDefault {}
extension DecodableDefault {
@propertyWrapper
public struct Wrapper<Source: DecodableDefaultSource> {
public typealias Value = Source.Value
public var wrappedValue = Source.defaultValue
public init() {}
}
}
extension DecodableDefault.Wrapper: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
wrappedValue = try container.decode(Value.self)
}
}
extension KeyedDecodingContainer {
public func decode<T>(_ type: DecodableDefault.Wrapper<T>.Type,
forKey key: Key) throws -> DecodableDefault.Wrapper<T> {
try decodeIfPresent(type, forKey: key) ?? .init()
}
}
extension DecodableDefault {
public typealias Source = DecodableDefaultSource
public typealias List = Decodable & ExpressibleByArrayLiteral
public typealias Map = Decodable & ExpressibleByDictionaryLiteral
public enum Sources {
public enum True: Source {
public static var defaultValue: Bool { true }
}
public enum False: Source {
public static var defaultValue: Bool { false }
}
public enum EmptyString: Source {
public static var defaultValue: String { "" }
}
public enum EmptyList<T: List>: Source {
public static var defaultValue: T { [] }
}
public enum EmptyMap<T: Map>: Source {
public static var defaultValue: T { [:] }
}
}
}
extension DecodableDefault {
public typealias True = Wrapper<Sources.True>
public typealias False = Wrapper<Sources.False>
public typealias EmptyString = Wrapper<Sources.EmptyString>
public typealias EmptyList<T: List> = Wrapper<Sources.EmptyList<T>>
public typealias EmptyMap<T: Map> = Wrapper<Sources.EmptyMap<T>>
}
extension DecodableDefault.Wrapper: Equatable where Value: Equatable {}
extension DecodableDefault.Wrapper: Hashable where Value: Hashable {}
extension DecodableDefault.Wrapper: Encodable where Value: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(wrappedValue)
}
}