Animatable AnyInsettableShape

System provides AnyShape type erasure that animates correctly. But system doesn't provide AnyInsettableShape. Here is my implementation of AnyInsettableShape (and AnyAnimatableData that is needed to support animation).

Let me know if there is simpler solution.

struct AnyInsettableShape: InsettableShape {
	private let _path: (CGRect) -> Path
	private let _inset: (CGFloat) -> AnyInsettableShape
	private let _getAnimatableData: () -> AnyAnimatableData
	private let _setAnimatableData: (_ data: AnyAnimatableData) -> AnyInsettableShape

	init<S>(_ shape: S) where S : InsettableShape {
		_path = { shape.path(in: $0) }
		_inset = { AnyInsettableShape(shape.inset(by: $0)) }
		_getAnimatableData = { AnyAnimatableData(shape.animatableData) }
		_setAnimatableData = { data in
			guard let otherData = data.rawValue as? S.AnimatableData else { assertionFailure(); return AnyInsettableShape(shape) }
			var shape = shape
			shape.animatableData = otherData
			return AnyInsettableShape(shape)
		}
	}

	var animatableData: AnyAnimatableData {
		get { _getAnimatableData() }
		set { self = _setAnimatableData(newValue) }
	}

	func path(in rect: CGRect) -> Path {
		_path(rect)
	}

	func inset(by amount: CGFloat) -> some InsettableShape {
		_inset(amount)
	}
}

struct AnyAnimatableData : VectorArithmetic {
	init<T : VectorArithmetic>(_ value: T) {
		self.init(optional: value)
	}
	
	private init<T : VectorArithmetic>(optional value: T?) {
		rawValue = value
		
		_scaleBy = { factor in
			(value != nil) ? AnyAnimatableData(value!.scaled(by: factor)) : .zero
		}
		_add = { other in
			AnyAnimatableData(value! + (other.rawValue as! T))
		}
		_subtract = { other in
			AnyAnimatableData(value! - (other.rawValue as! T))
		}
		_equal = { other in
			value! == (other.rawValue as! T)
		}
		_magnitudeSquared = {
			(value != nil) ? value!.magnitudeSquared : .zero
		}
		_zero = {
			AnyAnimatableData(T.zero)
		}
	}
	
	fileprivate let rawValue: (any VectorArithmetic)?
	private let _scaleBy: (_: Double) -> AnyAnimatableData
	private let _add: (_ other: AnyAnimatableData) -> AnyAnimatableData
	private let _subtract: (_ other: AnyAnimatableData) -> AnyAnimatableData
	private let _equal: (_ other: AnyAnimatableData) -> Bool
	private let _magnitudeSquared: () -> Double
	private let _zero: () -> AnyAnimatableData
	
	
	mutating func scale(by rhs: Double) {
		self = _scaleBy(rhs)
	}
	
	var magnitudeSquared: Double {
		_magnitudeSquared()
	}
	
	static let zero = AnyAnimatableData(optional: nil as Double?)
	
	@inline(__always)
	private var isZero: Bool { rawValue == nil }
	
	static func + (lhs: AnyAnimatableData, rhs: AnyAnimatableData) -> AnyAnimatableData {
		guard let (lhs, rhs) = fillZeroTypes(lhs, rhs) else { return .zero }
		return lhs._add(rhs)
	}
	
	static func - (lhs: AnyAnimatableData, rhs: AnyAnimatableData) -> AnyAnimatableData {
		guard let (lhs, rhs) = fillZeroTypes(lhs, rhs) else { return .zero }
		return lhs._subtract(rhs)
	}
	
	static func == (lhs: AnyAnimatableData, rhs: AnyAnimatableData) -> Bool {
		guard let (lhs, rhs) = fillZeroTypes(lhs, rhs) else { return true }
		return lhs._equal(rhs)
	}
	
	@inline(__always)
	private static func fillZeroTypes(_ lhs: AnyAnimatableData, _ rhs: AnyAnimatableData) -> (AnyAnimatableData, AnyAnimatableData)? {
		switch (!lhs.isZero, !rhs.isZero) {
		case (true, true): (lhs, rhs)
		case (true, false): (lhs, lhs._zero())
		case (false, true): (rhs._zero(), rhs)
		case (false, false): nil
		}
	}
}
Animatable AnyInsettableShape
 
 
Q