diff --git a/Sources/Adwaita/Model/Data Flow/Binding.swift b/Sources/Adwaita/Model/Data Flow/Binding.swift index 5b18a70..b19b32a 100644 --- a/Sources/Adwaita/Model/Data Flow/Binding.swift +++ b/Sources/Adwaita/Model/Data Flow/Binding.swift @@ -111,3 +111,38 @@ public struct Binding { } } + +extension Binding where Value: MutableCollection { + + /// Get a child at a certain index of the array as a binding. + /// - Parameters: + /// - index: The child's index. + /// - defaultValue: The value used if the index is out of range does not exist. + /// - Returns: The child as a binding. + public subscript(safe index: Value.Index?, default defaultValue: Value.Element) -> Binding { + .init { + if let index, wrappedValue.indices.contains(index) { + return wrappedValue[index] ?? defaultValue + } + return defaultValue + } set: { newValue in + if let index, wrappedValue.indices.contains(index) { + wrappedValue[index] = newValue + } + } + } + +} + +extension Binding where Value: MutableCollection, Value.Element: Identifiable { + + /// Get a child of the array with a certain id as a binding. + /// - Parameters: + /// - id: The child's id. + /// - defaultValue: The value used if the index is out of range does not exist. + /// - Returns: The child as a binding. + public subscript(id id: Value.Element.ID?, default defaultValue: Value.Element) -> Binding { + self[safe: wrappedValue.firstIndex { $0.id == id }, default: defaultValue] + } + +} diff --git a/Sources/Adwaita/Model/Extensions/Array.swift b/Sources/Adwaita/Model/Extensions/Array.swift index 6af6333..e819577 100644 --- a/Sources/Adwaita/Model/Extensions/Array.swift +++ b/Sources/Adwaita/Model/Extensions/Array.swift @@ -105,24 +105,19 @@ extension Array { } -extension Binding where Value: MutableCollection { +extension Array where Element: Identifiable { - /// Get a child at a certain index of the array as a binding. + /// Accesses the element with a certain id safely. /// - Parameters: - /// - index: The child's index. - /// - defaultValue: The value used if the index is out of range does not exist. - /// - Returns: The child as a binding. - public subscript(safe index: Value.Index?, default defaultValue: Value.Element) -> Binding { - .init { - if let index, wrappedValue.indices.contains(index) { - return wrappedValue[index] ?? defaultValue - } - return defaultValue - } set: { newValue in - if let index, wrappedValue.indices.contains(index) { - wrappedValue[index] = newValue - } - } + /// - id: The child's id. + /// + /// Access and set elements the safe way: + /// ```swift + /// var array = ["Hello", "World"] + /// print(array[safe: 2] ?? "Out of range") + /// ``` + public subscript(id id: Element.ID) -> Element? { + self[safe: firstIndex { $0.id == id }] } }