From 5b3d38b225900edd5bd96ee4528f11951e34120d Mon Sep 17 00:00:00 2001 From: Kyle Date: Sun, 3 Dec 2023 22:38:17 +0800 Subject: [PATCH] Add AccessibilityBoundedNumber init implementation --- .../internal/AccessibilityBoundedNumber.swift | 43 ++++++++++++++++--- .../ClosedRange+AccessibilityNumeric.swift | 17 ++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 Sources/OpenSwiftUI/Accessibility/internal/ClosedRange+AccessibilityNumeric.swift diff --git a/Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift b/Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift index a9cbbeb..113a57d 100644 --- a/Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift +++ b/Sources/OpenSwiftUI/Accessibility/internal/AccessibilityBoundedNumber.swift @@ -25,10 +25,10 @@ private protocol AbstractAnyAccessibilityValue: Codable { // MARK: - AnyAccessibilityValue -struct AnyAccessibilityValue/*: AbstractAnyAccessibilityValue*/ { +struct AnyAccessibilityValue { private var base: AbstractAnyAccessibilityValue - init(_ base: Value) { + init(_ base: some Codable & AccessibilityValue) { self.base = ConcreteBase(base: base) } } @@ -65,6 +65,23 @@ extension AnyAccessibilityValue: Codable { } } +extension AnyAccessibilityValue: AbstractAnyAccessibilityValue { + var localizedDescription: String? { base.localizedDescription } + var displayDescription: String? { base.displayDescription } + var value: Any { base.value } + var minValue: Any? { base.minValue } + var maxValue: Any? { base.maxValue } + var step: Any? { base.step } + var type: AnyAccessibilityValueType { base.type } + func `as`(_ type: Value.Type) -> Value? where Value: AccessibilityValue { + base.as(type) + } + + fileprivate func isEqual(to value: AbstractAnyAccessibilityValue) -> Bool { + base.isEqual(to: value) + } +} + // MARK: AnyAccessibilityValue.ConcreateBase extension AnyAccessibilityValue { @@ -83,9 +100,10 @@ extension AnyAccessibilityValue.ConcreteBase: AbstractAnyAccessibilityValue { var maxValue: Any? { base.maxValue } var step: Any? { base.step } var type: AnyAccessibilityValueType { Base.type } - func `as`(_ type: Value.Type) -> Value? where Value : AccessibilityValue { + func `as`(_: Value.Type) -> Value? where Value: AccessibilityValue { base as? Value } + func isEqual(to value: AbstractAnyAccessibilityValue) -> Bool { base == (value as? Self)?.base } @@ -99,9 +117,22 @@ struct AccessibilityBoundedNumber { var upperBound: AccessibilityNumber? var stride: AccessibilityNumber? - // TODO - init?(for value: S, in range: ClosedRange?, by stride: S.Stride?) { - return nil + init?(for value: S, in range: ClosedRange?, by strideValue: S.Stride?) { + let clampedValue = range.map { value.clamped(to: $0) } + let newValue = clampedValue ?? value + guard let numericValue = newValue as? AccessibilityNumeric, + let numberValue = numericValue.asNumber() else { + return nil + } + number = numberValue + if let range { + lowerBound = range.minimumValue?.asNumber() + upperBound = range.maximumValue?.asNumber() + } + if let strideValue, + let numericStride = strideValue as? AccessibilityNumeric { + stride = numericStride.asNumber() + } } } diff --git a/Sources/OpenSwiftUI/Accessibility/internal/ClosedRange+AccessibilityNumeric.swift b/Sources/OpenSwiftUI/Accessibility/internal/ClosedRange+AccessibilityNumeric.swift new file mode 100644 index 0000000..0d5f319 --- /dev/null +++ b/Sources/OpenSwiftUI/Accessibility/internal/ClosedRange+AccessibilityNumeric.swift @@ -0,0 +1,17 @@ +extension ClosedRange where Bound: Strideable { + var minimumValue: AccessibilityNumeric? { + guard let value = lowerBound as? AccessibilityNumeric, + value.isValidMinValue else { + return nil + } + return value + } + + var maximumValue: AccessibilityNumeric? { + guard let value = upperBound as? AccessibilityNumeric, + value.isValidMaxValue else { + return nil + } + return value + } +}