-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathError.swift
More file actions
141 lines (114 loc) · 4.36 KB
/
Error.swift
File metadata and controls
141 lines (114 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//
// Error.swift
// SwiftAndroid
//
// Created by Alsey Coleman Miller on 7/6/25.
//
#if canImport(Android)
import Android
import AndroidNDK
#endif
/// Android NDK Binder Error
public struct AndroidBinderError: Error {
public let errorCode: ErrorCode
internal let file: StaticString
internal let function: StaticString
internal init(
_ errorCode: ErrorCode,
file: StaticString = #file,
function: StaticString = #function
) {
assert(errorCode.rawValue != STATUS_OK)
self.errorCode = errorCode
self.file = file
self.function = function
}
}
// MARK: - Properties
public extension AndroidBinderError {
var message: String {
let status = Status(errorCode: errorCode)
return status.description
}
}
// MARK: - CustomStringConvertible
extension AndroidBinderError: CustomStringConvertible {
public var description: String {
message
}
}
// MARK: - Supporting Types
public extension AndroidBinderError {
/**
* Low-level status types for use in binder. This is the least preferable way to
* return an error for binder services (where binder_exception_t should be used,
* particularly EX_SERVICE_SPECIFIC).
*/
struct ErrorCode: RawRepresentable, Equatable, Hashable, Sendable {
public let rawValue: Int32
public init(rawValue: Int32) {
self.init(rawValue)
}
private init(_ raw: Int32) {
assert(raw != 0)
self.rawValue = raw
}
private init(_ raw: Int) {
self.init(Int32(raw))
}
}
}
// MARK: - Constants
public extension AndroidBinderError.ErrorCode {
static var unknown: Self { .init(STATUS_UNKNOWN_ERROR) } // INT32_MIN
static var noMemory: Self { .init(STATUS_NO_MEMORY) } // -ENOMEM
static var invalidOperation: Self { .init(STATUS_INVALID_OPERATION) } // -ENOSYS
static var badValue: Self { .init(STATUS_BAD_VALUE) } // -EINVAL
static var badType: Self { .init(STATUS_BAD_TYPE) } // (STATUS_UNKNOWN_ERROR + 1)
static var nameNotFound: Self { .init(STATUS_NAME_NOT_FOUND) } // -ENOENT
static var permissionDenied: Self { .init(STATUS_PERMISSION_DENIED) } // -EPERM
static var noInit: Self { .init(STATUS_NO_INIT) } // -ENODEV
static var alreadyExists: Self { .init(STATUS_ALREADY_EXISTS) } // -EEXIST
static var deadObject: Self { .init(STATUS_DEAD_OBJECT) } // -EPIPE
static var failedTransaction: Self { .init(STATUS_FAILED_TRANSACTION) } // (STATUS_UNKNOWN_ERROR + 2)
static var badIndex: Self { .init(STATUS_BAD_INDEX) } // -EOVERFLOW
static var notEnoughData: Self { .init(STATUS_NOT_ENOUGH_DATA) } // -ENODATA
static var wouldBlock: Self { .init(STATUS_WOULD_BLOCK) } // -EWOULDBLOCK
static var timedOut: Self { .init(STATUS_TIMED_OUT) } // -ETIMEDOUT
static var unknownTransaction: Self { .init(STATUS_UNKNOWN_TRANSACTION) } // -EBADMSG
static var fdsNotAllowed: Self { .init(STATUS_FDS_NOT_ALLOWED) } // (STATUS_UNKNOWN_ERROR + 7)
static var unexpectedNull: Self { .init(STATUS_UNEXPECTED_NULL) } // (STATUS_UNKNOWN_ERROR + 8)
}
// MARK: - Internal Extensions
internal extension binder_status_t {
func mapError(
file: StaticString = #file,
function: StaticString = #function
) -> Result<Void, AndroidBinderError> {
mapError((), file: file, function: function)
}
func mapError<T>(
_ value: T,
file: StaticString = #file,
function: StaticString = #function
) -> Result<T, AndroidBinderError> {
guard self != STATUS_OK else {
return .success(value)
}
let errorCode = AndroidBinderError.ErrorCode(rawValue: self)
let error = AndroidBinderError(errorCode, file: file, function: function)
return .failure(error)
}
func mapError<T: ~Copyable>(
as _: T.Type,
file: StaticString = #file,
function: StaticString = #function
) -> Result<T, AndroidBinderError> {
guard self != STATUS_OK else {
fatalError("mapError(as:) must only be used for non-STATUS_OK results.")
}
let errorCode = AndroidBinderError.ErrorCode(rawValue: self)
let error = AndroidBinderError(errorCode, file: file, function: function)
return .failure(error)
}
}