Multiple Types on a Struct Property

I have three structs that are codable and identifiable: SetEntry, TimeEntry, and DistanceEntry. I have another struct called WorkoutLog which takes in an Exercise and has a property entry. What I am trying to do is allow entry to be any of the above entry types. I thought about using a protocol, but I couldn't get it decodable and I don't know how to fix that. I know that with protocols you have to use the any Protocol syntax and I think that is what is limiting me from making it codable, but I can't really be sure. I also know that we could use enums with associated types but I don't know if this is good for production-level code. Any insights would be greatly appreciated.

struct SetEntry: Identifiable, Codable {
    var id: UUID
    var reps: Int
    var weight: Double
    
    init(id: UUID = UUID(), reps: Int, weight: Double) {
        self.id = id
        self.reps = reps
        self.weight = weight
    }
}
struct DistanceEntry: Codable, Identifiable {
    var id: UUID
    var distanceInMeters: Int
    
    init(id: UUID = UUID(), distanceInMeters: Int) {
        self.id = id
        self.distanceInMeters = distanceInMeters
    }
}
struct TimeEntry: Identifiable, Codable {
    var id: UUID
    var timeInSeconds: Int
    
    init(id: UUID = UUID(), timeInSeconds: Int) {
        self.id = id
        self.timeInSeconds = timeInSeconds
    }
}
struct WorkoutLog: Identifiable, Codable {
    var id: UUID
    var exercise: Exercise
    var entry: ???
}

I think what you are searching a generic parameter (learn about them here: https://www.youtube.com/watch?v=a3AH0ItFTKU.

here is an example a bit like what you are doing:


struct struct1: Codable, Identifiable {
    var id = UUID()
    var name: String
}
struct struct2: Codable, Identifiable {
    var id = UUID()
    var Number: Int
}

struct SuperStruct<T: Codable>: Codable, Identifiable {
    var id = UUID()
    var something: T
}

var Object: SuperStruct = SuperStruct(something: struct1(name: "Hello"))
var ObjectAgain: SuperStruct = SuperStruct(something: struct2(Number: 2))

I hope this helps you,

Sam

You don't show the full code, so hard to seriously test.

But I would try to use enum with associated values:

enum GenericEntry : Codable {
    case set(SetEntry)
    case dist(DistanceEntry)
    case time(TimeEntry)
}

struct WorkoutLog: Identifiable, Codable {
    var id: UUID
    var exercise: Exercise
    var entry: GenericEntry
}

Which you can use with various patterns:

let distEntry = DistanceEntry(distanceInMeters: 100)
let entry = GenericEntry.dist(distEntry)
let wo = WorkoutLog(id: UUID(), exercise: "Exercise", entry: entry)

if case let GenericEntry.dist(someDist) = wo.entry {
    print(someDist.distanceInMeters)
}

switch wo.entry {
    case .set(let aSet): print("With switch", aSet.weight)
    case .dist(let aDist): print("With switch", aDist.distanceInMeters)
    case .time(let aTime): print("With switch", aTime.timeInSeconds)
}

For the static property problem :


struct struct1: Codable, Identifiable {
    var id = UUID()
    var name: String
}
struct struct2: Codable, Identifiable {
    var id = UUID()
    var Number: Int
}

struct SuperStruct<T: Codable & Identifiable>: Codable, Identifiable {
    var id = UUID()
    var something: T
}
extension SuperStruct where T == struct1 {
    static let test1 = SuperStruct(something: struct1(name: ""))
}
extension SuperStruct where T == struct2 {
    static let test2 = SuperStruct(something: struct2(Number: 10))
}


class master {
    let parameterOne = SuperStruct.test1
    var parameterTwo = SuperStruct(something: struct2(Number: 100))
    
    static let def = SuperStruct(something: struct1(name: "default"))
}

what it does is it adds an extension for each structs that you want to add as static property so inside extension SuperStruct where T == struct1 the only type that T can have is struct1, if you do this you can use a static property in the extension then access it with SuperStruct.test1 or SuperStruct.test2

for the as! T thing I don't think it's an issue as you do not have an optional so you should not have any problems as you can always unwrap it with !. I'm not sure why it's asking for the as!, it doesn't always ask me so...?

Multiple Types on a Struct Property
 
 
Q