i’ve got tons of “stats” structures that look like:
@frozen public
struct ByStatus
{
public
var ok:Int
public
var notModified:Int
public
var multipleChoices:Int
public
var redirectedPermanently:Int
public
var redirectedTemporarily:Int
public
var notFound:Int
public
var errored:Int
public
var unauthorized:Int
}
@frozen public
struct ByLanguage
{
public
var zh:Int
public
var es:Int
public
var en:Int
public
var ar:Int
public
var hi:Int
public
var bn:Int
public
var pt:Int
public
var ru:Int
public
var other:Int
public
var none:Int
}
et cetera, et cetera.
each stored property has some associated strings for things like display text and css class, and iterating over wide tuples is awkward and takes a long time to format:
for (state, style, value):(String, String, Int) in
[
("Multiple Choices", "multiple-choices", self.multipleChoices),
("Not Modified", "not-modified", self.notModified),
("OK", "ok", self.ok),
("Redirected Permanently", "redirected-permanently", self.redirectedPermanently),
("Redirected Temporarily", "redirected-temporarily", self.redirectedTemporarily),
("Not Found", "not-found", self.notFound),
("Errored", "errored", self.errored),
("Unauthorized", "unauthorized", self.unauthorized),
]
{
if value > 0
{
chart.append(.init(
stratum: stratum,
state: state,
value: value,
class: "status \(style)"))
}
}
i would much rather have this information tied to the properties themselves, using something like
@frozen public
struct ByStatus
{
@Statistic(class: "ok", display: "OK")
public
var ok:Int
@Statistic(class: "not-modified", display: "Not Modified")
public
var notModified:Int
...
but we cannot actually define such a property wrapper using a concrete type Statistic
, because we obviously do not want to store a constant string pointer inside every ByStatus
structure!
so we need to define a bunch of bespoke type-constants to push this information into the generics system.
extension ByStatus
{
@frozen public
enum OK:StatisticalCategory
{
static
var style:String { "ok" }
}
}
extension ByStatus
{
@frozen public
enum NotModified:StatisticalCategory
{
static
var style:String { "not-modified" }
}
}
...
@frozen public
struct ByStatus
{
@Statistic<OK>
public
var ok:Int
@Statistic<NotModified>
public
var notModified:Int
...
}
but by now, you have to wonder if the cure is worse than the disease.
surely there must be a better way?