Equatable intersects with other comparing parts in project
mojidabckuu opened this issue · comments
Diffable uses == operator to determine if two objects are same or not. If you are using ListDiff when some model stores visual information and in the same time is a part of another system which is basing on == operator it breaks the logic.
For example you have a Post
and each post has a badge of views.
class Post: Diffable {
var id: Int
var badge: Int
func ==(lhs: Post, rhs: Post) -> Bool { return lhs.id == rhs.id && lhs.badge == rhs.badge }
var diffIdentifier: AnyHashable { return self.id }
}
The PK is id attribute. Badge is just a number to render and doesn't represent object itself. Let's assume you want to refresh your views since badge is not the same. Then badge becomes a part of ==. So if you are trying to lookup though the array of posts having id only then it requires write blocks like where: { $0.id == some_id }
which is not correct and other libs based on == couldn't success to find an object, etc.
Expected behaviour is to have an independent operator/method to differentiate two objects for updates.
I think Diffable is mostly only providing an identity mechanism. The equality is handled by Equatable.
ListDiff/Sources/ListDiff.swift
Line 95 in 7ab9495
The part where equatable come into play is in these lines where we detect if the the 2 identical element are not equal.
ListDiff/Sources/ListDiff.swift
Lines 147 to 153 in 7ab9495
I think semantically wise, this is correct. If something is not equal, ListDiff will let you know about it.
In your case, you might want a ViewModel representation so that you does not need to populate your model with view related attributes.
struct PostViewModel: Diffablel {
post: Post
badge: Int
var diffIdentifier: Int {
return self.post.id;
}
}
Pardon me if there's syntax error, I'm kinda rusty with Swift nowadays.
That's correct. I propose to add an extra operator to compare 2 elements in terms of diffing.