Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

CKeyTypes.swift

v0.1.0-build.85 Latest Commit ede38f5

Size
4.9 KB
Lines
132
Language
swift
SHA-256
9a7d9d8a77bb…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1import CKeyCodec
2import Foundation
3
4/// An error reported by the CKey core, with its diagnostic message.
5public struct CKeyError: Error, Equatable, CustomStringConvertible {
6 /// The core's status codes (`ckey_status`), plus configuration errors
7 /// raised by the Swift layer itself.
8 public enum Code: Int, Sendable {
9 case invalidArgument = 1
10 case unsupportedProfile = 2
11 case insufficientBuffer = 3
12 case internalError = 4
13 case uncorrectable = 5
14 case integrityFailure = 6
15 /// An image could not be read or created (Core Graphics).
16 case imageConversion = 100
17 /// A configuration value is out of range (for example a telemetry
18 /// mode other than 0, 1 or 2).
19 case invalidConfiguration = 101
20 /// Camera access was denied or restricted by the user or by policy.
21 case cameraAccessDenied = 102
22 /// No usable camera, or it could not be configured or started.
23 case cameraUnavailable = 103
24 }
25
26 public let code: Code
27 public let message: String
28
29 public init(_ code: Code, _ message: String) {
30 self.code = code
31 self.message = message
32 }
33
34 public var description: String { "CKeyError(\(code)): \(message)" }
35
36 /// Wraps a non-OK core status. Internal plumbing shared by the CKey module.
37 public static func core(_ status: ckey_status, _ diagnostics: ckey_diagnostics? = nil,
38 _ fallback: String = "") -> CKeyError {
39 let code = Code(rawValue: Int(status.rawValue)) ?? .internalError
40 var text = fallback
41 if let diagnostics {
42 let message = CKeyError.string(fromDiagnostics: diagnostics)
43 if !message.isEmpty { text = message }
44 }
45 if text.isEmpty { text = "CKey core status \(status.rawValue)" }
46 return CKeyError(code, text)
47 }
48
49 static func string(fromDiagnostics diagnostics: ckey_diagnostics) -> String {
50 withUnsafeBytes(of: diagnostics.message) { raw -> String in
51 let bytes = raw.bindMemory(to: UInt8.self)
52 let end = bytes.firstIndex(of: 0) ?? bytes.count
53 return String(decoding: bytes[0..<end], as: UTF8.self)
54 }
55 }
56}
57
58/// Profile 0 layout family.
59public enum CKeyLayout: Int, Sendable, CaseIterable {
60 /// Format 0.27: the default screen and print layout.
61 case standard = 0
62 /// Format 0.28 ("P0.1"): larger marks and gaps for small prints, at a
63 /// lower capacity per version.
64 case print = 1
65}
66
67/// The optical profile a symbol was read as.
68public enum CKeyProfile: Int, Sendable, CaseIterable {
69 /// Profile 0, the scalable family (versions 1 to 31). See `CKeyResult.layout`.
70 case scalable = 0
71 /// Profile 1: a 16-byte locator.
72 case locator = 1
73 /// Profile 2: text, up to 200 bytes.
74 case text = 2
75 /// Profile 3: extended, up to 2,048 bytes.
76 case extended = 3
77}
78
79/// A decoded symbol.
80public struct CKeyResult: Equatable, Sendable {
81 /// The payload bytes, verified by Reed-Solomon correction and CRC-32C.
82 public let bytes: Data
83 /// The payload as text when it is valid UTF-8 without control characters
84 /// other than tab, LF and CR (spec/CKey-Payload-Conventions.md); `nil`
85 /// for binary payloads.
86 public let text: String?
87 public let profile: CKeyProfile
88 /// Profile 0 version (1...31); 0 for Profiles 1 to 3.
89 public let version: Int
90 /// Profile 0 layout; `nil` for Profiles 1 to 3.
91 public let layout: CKeyLayout?
92
93 public init(bytes: Data, profile: CKeyProfile, version: Int = 0, layout: CKeyLayout? = nil) {
94 self.bytes = bytes
95 self.text = CKeyPayload.text(from: bytes)
96 self.profile = profile
97 self.version = version
98 self.layout = layout
99 }
100
101 /// The telemetry profile code (`ckey_telemetry_profile`): 0 = P0,
102 /// 1 = P0.1 (print layout), 2 = P1, 3 = P2, 4 = P3.
103 public var telemetryProfileCode: UInt32 {
104 switch profile {
105 case .scalable: return layout == .print ? 1 : 0
106 case .locator: return 2
107 case .text: return 3
108 case .extended: return 4
109 }
110 }
111
112 /// A short human-readable profile name, e.g. "Profile 0 · v3".
113 public var profileDescription: String {
114 switch profile {
115 case .scalable: return layout == .print ? "Profile 0.1 · print · v\(version)" : "Profile 0 · v\(version)"
116 case .locator: return "Profile 1 · Locator"
117 case .text: return "Profile 2 · Text"
118 case .extended: return "Profile 3 · Extended"
119 }
120 }
121}
122
123/// Versions of the linked core.
124public enum CKeyCoreInfo {
125 /// The core's software version, e.g. "0.1.0-build.63" (the repository's VERSION).
126 public static var softwareVersion: String {
127 ckey_get_software_version().map { String(cString: $0) } ?? "0.0.0"
128 }
129
130 /// The C ABI version of the linked core.
131 public static var abiVersion: UInt32 { ckey_get_abi_version() }
132}