feat: add optional loop field to DeviceInfo
This commit is contained in:
@@ -7,11 +7,13 @@ public struct DeviceInfo: Equatable {
|
|||||||
public let size: String
|
public let size: String
|
||||||
public let brand: String
|
public let brand: String
|
||||||
public let powerlevel: Int
|
public let powerlevel: Int
|
||||||
|
/// 播放模式(旧固件无此字段时为 nil)
|
||||||
|
public let loop: PlayMode?
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DeviceInfo: Codable {
|
extension DeviceInfo: Codable {
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case allspace, freespace, name, size, brand, powerlevel
|
case allspace, freespace, name, size, brand, powerlevel, loop
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
@@ -35,6 +37,13 @@ extension DeviceInfo: Codable {
|
|||||||
// allspace/freespace: may come as number, string, or be missing
|
// allspace/freespace: may come as number, string, or be missing
|
||||||
allspace = Self.decodeFlexibleUInt64(container: container, key: .allspace)
|
allspace = Self.decodeFlexibleUInt64(container: container, key: .allspace)
|
||||||
freespace = Self.decodeFlexibleUInt64(container: container, key: .freespace)
|
freespace = Self.decodeFlexibleUInt64(container: container, key: .freespace)
|
||||||
|
|
||||||
|
// loop: optional. Accept Int 0/1; anything else → nil.
|
||||||
|
if let raw = try? container.decode(Int.self, forKey: .loop), let mode = PlayMode(rawValue: raw) {
|
||||||
|
loop = mode
|
||||||
|
} else {
|
||||||
|
loop = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func decodeFlexibleUInt64(
|
private static func decodeFlexibleUInt64(
|
||||||
|
|||||||
@@ -20,3 +20,33 @@ final class PlayModeTests: XCTestCase {
|
|||||||
XCTAssertEqual(decoded, .single)
|
XCTAssertEqual(decoded, .single)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class DeviceInfoLoopTests: XCTestCase {
|
||||||
|
private func decode(_ json: String) throws -> DeviceInfo {
|
||||||
|
try JSONDecoder().decode(DeviceInfo.self, from: Data(json.utf8))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoopMissingDecodesToNil() throws {
|
||||||
|
let json = #"{"name":"d1","size":"360","brand":"duomi","powerlevel":80,"allspace":1024,"freespace":512}"#
|
||||||
|
let info = try decode(json)
|
||||||
|
XCTAssertNil(info.loop)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoopZeroDecodesToSingle() throws {
|
||||||
|
let json = #"{"name":"d1","size":"360","brand":"duomi","powerlevel":80,"allspace":1024,"freespace":512,"loop":0}"#
|
||||||
|
let info = try decode(json)
|
||||||
|
XCTAssertEqual(info.loop, .single)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoopOneDecodesToLoop() throws {
|
||||||
|
let json = #"{"name":"d1","size":"360","brand":"duomi","powerlevel":80,"allspace":1024,"freespace":512,"loop":1}"#
|
||||||
|
let info = try decode(json)
|
||||||
|
XCTAssertEqual(info.loop, .loop)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testLoopInvalidValueDecodesToNil() throws {
|
||||||
|
let json = #"{"name":"d1","size":"360","brand":"duomi","powerlevel":80,"allspace":1024,"freespace":512,"loop":7}"#
|
||||||
|
let info = try decode(json)
|
||||||
|
XCTAssertNil(info.loop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user