95 lines
2.9 KiB
Swift
95 lines
2.9 KiB
Swift
import Foundation
|
|
|
|
/// A lab protocol document. Named `LabProtocol` to avoid collision with the Swift keyword `Protocol`.
|
|
/// The server returns snake_case keys for this model.
|
|
public struct LabProtocol: Codable, Identifiable, Sendable {
|
|
public let id: String
|
|
public var userId: String?
|
|
public var title: String
|
|
public var content: String
|
|
public var fileUrl: String?
|
|
public var analysisResults: AnyCodable?
|
|
public var createdAt: String?
|
|
public var updatedAt: String?
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case id
|
|
case userId = "user_id"
|
|
case title
|
|
case content
|
|
case fileUrl = "file_url"
|
|
case analysisResults = "analysis_results"
|
|
case createdAt = "created_at"
|
|
case updatedAt = "updated_at"
|
|
}
|
|
|
|
public init(
|
|
id: String = "",
|
|
userId: String? = nil,
|
|
title: String = "",
|
|
content: String = "",
|
|
fileUrl: String? = nil,
|
|
analysisResults: AnyCodable? = nil,
|
|
createdAt: String? = nil,
|
|
updatedAt: String? = nil
|
|
) {
|
|
self.id = id
|
|
self.userId = userId
|
|
self.title = title
|
|
self.content = content
|
|
self.fileUrl = fileUrl
|
|
self.analysisResults = analysisResults
|
|
self.createdAt = createdAt
|
|
self.updatedAt = updatedAt
|
|
}
|
|
}
|
|
|
|
// MARK: - AnyCodable helper
|
|
|
|
public struct AnyCodable: Codable, @unchecked Sendable {
|
|
public let value: Any
|
|
|
|
public init(_ value: Any) {
|
|
self.value = value
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
if let intVal = try? container.decode(Int.self) {
|
|
value = intVal
|
|
} else if let doubleVal = try? container.decode(Double.self) {
|
|
value = doubleVal
|
|
} else if let boolVal = try? container.decode(Bool.self) {
|
|
value = boolVal
|
|
} else if let stringVal = try? container.decode(String.self) {
|
|
value = stringVal
|
|
} else if let arrayVal = try? container.decode([AnyCodable].self) {
|
|
value = arrayVal
|
|
} else if let dictVal = try? container.decode([String: AnyCodable].self) {
|
|
value = dictVal
|
|
} else {
|
|
value = NSNull()
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
switch value {
|
|
case let intVal as Int:
|
|
try container.encode(intVal)
|
|
case let doubleVal as Double:
|
|
try container.encode(doubleVal)
|
|
case let boolVal as Bool:
|
|
try container.encode(boolVal)
|
|
case let stringVal as String:
|
|
try container.encode(stringVal)
|
|
case let arrayVal as [AnyCodable]:
|
|
try container.encode(arrayVal)
|
|
case let dictVal as [String: AnyCodable]:
|
|
try container.encode(dictVal)
|
|
default:
|
|
try container.encodeNil()
|
|
}
|
|
}
|
|
}
|