diff --git a/Delta.xcodeproj/project.pbxproj b/Delta.xcodeproj/project.pbxproj index a77da43..1d5d9c3 100644 --- a/Delta.xcodeproj/project.pbxproj +++ b/Delta.xcodeproj/project.pbxproj @@ -185,6 +185,8 @@ D5D797E6298D946200738869 /* Contributor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D797E5298D946200738869 /* Contributor.swift */; }; D5D797E9298DCC7300738869 /* cheatbase.zip in Resources */ = {isa = PBXBuildFile; fileRef = D5D797E7298DC9E200738869 /* cheatbase.zip */; }; D5D7C1FA29E60EDE00663793 /* libDeltaFeatures.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5D7C1F129E60DFF00663793 /* libDeltaFeatures.a */; }; + D5D7C20129E60F2000663793 /* LocalizedOptionValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D7C1E829E5FCDE00663793 /* LocalizedOptionValue.swift */; }; + D5D7C20229E60F2000663793 /* OptionValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D7C1E629E5F90200663793 /* OptionValue.swift */; }; D5D7C20429E60F2000663793 /* Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A9BFFD29DDECF100A8D610 /* Feature.swift */; }; D5D7C20829E616CF00663793 /* FeatureContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D7C20729E616CF00663793 /* FeatureContainer.swift */; }; D5F82FB82981D3AC00B229AF /* LegacySearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F82FB72981D3AC00B229AF /* LegacySearchBar.swift */; }; @@ -419,6 +421,8 @@ D5AAF27629884F8600F21ACF /* CheatDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheatDevice.swift; sourceTree = ""; }; D5D797E5298D946200738869 /* Contributor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contributor.swift; sourceTree = ""; }; D5D797E7298DC9E200738869 /* cheatbase.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = cheatbase.zip; sourceTree = ""; }; + D5D7C1E629E5F90200663793 /* OptionValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptionValue.swift; sourceTree = ""; }; + D5D7C1E829E5FCDE00663793 /* LocalizedOptionValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedOptionValue.swift; sourceTree = ""; }; D5D7C1F129E60DFF00663793 /* libDeltaFeatures.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libDeltaFeatures.a; sourceTree = BUILT_PRODUCTS_DIR; }; D5D7C20729E616CF00663793 /* FeatureContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureContainer.swift; sourceTree = ""; }; D5F82FB72981D3AC00B229AF /* LegacySearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegacySearchBar.swift; sourceTree = ""; }; @@ -976,6 +980,8 @@ children = ( D5A9C01929DDFBDD00A8D610 /* SettingsName.swift */, D54F710129E89DCB009C069A /* SettingsUserInfoKey.swift */, + D5D7C1E629E5F90200663793 /* OptionValue.swift */, + D5D7C1E829E5FCDE00663793 /* LocalizedOptionValue.swift */, ); path = Types; sourceTree = ""; @@ -1518,8 +1524,10 @@ D5D7C20829E616CF00663793 /* FeatureContainer.swift in Sources */, D517F6BA29E730DA000D14D0 /* SettingsName.swift in Sources */, D5D7C20429E60F2000663793 /* Feature.swift in Sources */, + D5D7C20129E60F2000663793 /* LocalizedOptionValue.swift in Sources */, D54F710429E89DFC009C069A /* NotificationName+Settings.swift in Sources */, D54F710229E89DCB009C069A /* SettingsUserInfoKey.swift in Sources */, + D5D7C20229E60F2000663793 /* OptionValue.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/DeltaFeatures/Types/LocalizedOptionValue.swift b/DeltaFeatures/Types/LocalizedOptionValue.swift new file mode 100644 index 0000000..cc3a3ce --- /dev/null +++ b/DeltaFeatures/Types/LocalizedOptionValue.swift @@ -0,0 +1,60 @@ +// +// LocalizedOptionValue.swift +// Delta +// +// Created by Riley Testut on 4/11/23. +// Copyright © 2023 Riley Testut. All rights reserved. +// + +import SwiftUI + +public protocol LocalizedOptionValue: OptionValue, Hashable /* Identifiable */ // We don't want to implicitly conform types we don't own to `Identifiable`. +{ + static var localizedNilDescription: Text { get } + + var localizedDescription: Text { get } +} + +public extension LocalizedOptionValue +{ + static var localizedNilDescription: Text { + Text("None") + } +} + +// Provide `localizedDescription` implementation for standard library types. +public extension LocalizedOptionValue where Self: CustomStringConvertible +{ + var localizedDescription: Text { + Text(String(describing: self)) + } +} + +extension Int: LocalizedOptionValue {} +extension Int8: LocalizedOptionValue {} +extension Int16: LocalizedOptionValue {} +extension Int32: LocalizedOptionValue {} +extension Int64: LocalizedOptionValue {} + +extension UInt: LocalizedOptionValue {} +extension UInt8: LocalizedOptionValue {} +extension UInt16: LocalizedOptionValue {} +extension UInt32: LocalizedOptionValue {} +extension UInt64: LocalizedOptionValue {} + +extension Float: LocalizedOptionValue {} +extension Double: LocalizedOptionValue {} + +extension String: LocalizedOptionValue {} +extension Bool: LocalizedOptionValue {} + +extension Optional: LocalizedOptionValue where Wrapped: LocalizedOptionValue +{ + public var localizedDescription: Text { + switch self + { + case .none: return Wrapped.localizedNilDescription + case .some(let value): return value.localizedDescription + } + } +} diff --git a/DeltaFeatures/Types/OptionValue.swift b/DeltaFeatures/Types/OptionValue.swift new file mode 100644 index 0000000..ff11ccf --- /dev/null +++ b/DeltaFeatures/Types/OptionValue.swift @@ -0,0 +1,21 @@ +// +// OptionValue.swift +// Delta +// +// Created by Riley Testut on 4/11/23. +// Copyright © 2023 Riley Testut. All rights reserved. +// + +import Foundation + +public protocol OptionValue +{ +} + +extension Data: OptionValue {} + +extension Optional: OptionValue where Wrapped: OptionValue {} + +extension Array: OptionValue where Element: OptionValue {} +extension Set: OptionValue where Element: OptionValue {} +extension Dictionary: OptionValue where Key: OptionValue, Value: OptionValue {}