From 7e3a797a694a04700ce2c03a23465d201fac7bc7 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Tue, 15 Dec 2020 18:26:18 -0800 Subject: [PATCH] Forbid class types for ItemContent and HeaderFooterContent --- CHANGELOG.md | 2 ++ .../Sources/HeaderFooter/HeaderFooter.swift | 2 ++ ListableUI/Sources/Internal/Validations.swift | 30 +++++++++++++++++++ ListableUI/Sources/Item/Item.swift | 2 ++ 4 files changed, 36 insertions(+) create mode 100644 ListableUI/Sources/Internal/Validations.swift diff --git a/CHANGELOG.md b/CHANGELOG.md index d44684371..3e28deac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added +- [Assert that `ItemContent` and `HeaderFooterContent` are value types](https://github.com/kyleve/Listable/pull/243). This is assumed by the framework and should be validated. + ### Removed ### Changed diff --git a/ListableUI/Sources/HeaderFooter/HeaderFooter.swift b/ListableUI/Sources/HeaderFooter/HeaderFooter.swift index 36934c00b..7bd6b16d4 100644 --- a/ListableUI/Sources/HeaderFooter/HeaderFooter.swift +++ b/ListableUI/Sources/HeaderFooter/HeaderFooter.swift @@ -45,6 +45,8 @@ public struct HeaderFooter : AnyHeaderFooter layout : HeaderFooterLayout = HeaderFooterLayout(), onTap : OnTap? = nil ) { + assertIsValueType(Content.self) + self.content = content self.sizing = sizing diff --git a/ListableUI/Sources/Internal/Validations.swift b/ListableUI/Sources/Internal/Validations.swift new file mode 100644 index 000000000..af05fa61d --- /dev/null +++ b/ListableUI/Sources/Internal/Validations.swift @@ -0,0 +1,30 @@ +// +// Validations.swift +// ListableUI +// +// Created by Kyle Van Essen on 12/15/20. +// + +import Foundation + + +/// Validates that the provided object is not a class type. +func assertIsValueType(_ valueType : Value.Type) { + + #if !DEBUG + return + #endif + + precondition( + valueType is AnyClass == false, + { + let typeName = String(describing: Value.self) + + return """ + `\(typeName)` must be a value type to work properly with Listable and value semantics. Instead, it was a class. + + Please convert your `\(typeName)` class from a `class` to a `struct` type. + """ + }() + ) +} diff --git a/ListableUI/Sources/Item/Item.swift b/ListableUI/Sources/Item/Item.swift index 99a8f346d..92b8ab7bf 100644 --- a/ListableUI/Sources/Item/Item.swift +++ b/ListableUI/Sources/Item/Item.swift @@ -70,6 +70,8 @@ public struct Item : AnyItem onMove : OnMove.Callback? = nil, onUpdate : OnUpdate.Callback? = nil ) { + assertIsValueType(Content.self) + self.content = content if let sizing = sizing {