I am having a bit of an access control conundrum when using structs in place of classes to achieve a more protocol oriented programming approach.
I am receiving different message types over the network, which in their raw form are simply an array of bytes.
So I start with a protocol. Note how the rawBytes
is marked only as { get }
so callers can't directly manipulate the raw bytes:
protocol NetworkDataRequest {
var rawBytes: [UInt8] { get }
}
I'm trying to be thread safe and use all the value type, protocol oriented goodness of Swift, so I now create my different message types using structs instead of classes, and adopt the protocol.
struct FileRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
}
struct ConnectionRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
}
All the different message types share a similar structure for the first 10 bytes, for example:
- byte[0] = permissionsByte
- byte[1] = connectionTypeByte
- etc...
Since I'm using structs I don't have inheritance. But I still need some way to have similar behavior between message types. OK, so I use a protocol extension:
extension NetworkDataRequest {
var permissionsByte: UInt8 {
get { return bytes[0] }
set { bytes[0] = newValue } //<-- Nope!
}
}
But oops! The rawBytes
is inaccessible:
Cannot assign through subscript: 'rawBytes' is a get-only property
Is there any way around this? Otherwise all my structs are going to have a lot of boilerplate code (sucks for me), or I'm going to have to open up the rawBytes (very bad)
struct FileRequest: NetworkDataRequest {
private(set) var rawBytes: [UInt8]
var permissionsByte: UInt8 {
get { return bytes[0] }
set { bytes[0] = newValue }
}
var connectionTypeByte: UInt8 {
get { return bytes[1] }
set { bytes[1] = newValue }
}
///etc...
}