fix(streaming): replace the token-kind trap with an exhaustive switch
The 22-case TokenType mapping was split across three initializers to stay under the complexity lint, leaving a preconditionFailure default the types could not prove unreachable, which also tripped the forbidden-patterns gate on every push. One exhaustive switch makes a new TokenType case a compile error instead of a runtime trap; the lint now ignores case statements when counting complexity, since exhaustive closed-enum switches are the point, not a smell.
This commit is contained in:
parent
b48a30f978
commit
20f080a9f7
@ -14,5 +14,10 @@ force_cast: error
|
|||||||
line_length:
|
line_length:
|
||||||
warning: 180
|
warning: 180
|
||||||
error: 180
|
error: 180
|
||||||
|
# Exhaustive switches over closed enums are the intended way to make
|
||||||
|
# impossible states unrepresentable; counting their cases as complexity
|
||||||
|
# pushes code toward split mappings with trapping defaults instead.
|
||||||
|
cyclomatic_complexity:
|
||||||
|
ignores_case_statements: true
|
||||||
trailing_comma:
|
trailing_comma:
|
||||||
mandatory_comma: true
|
mandatory_comma: true
|
||||||
|
|||||||
@ -56,13 +56,11 @@ extension PureYAML.Streaming.Token {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension PureYAML.Streaming.Token.Kind {
|
extension PureYAML.Streaming.Token.Kind {
|
||||||
/// A mechanical 1:1 mapping over all 22 `TokenType` cases, split across
|
/// A mechanical 1:1 mapping over all 22 `TokenType` cases in one
|
||||||
/// three initializers purely to keep each switch's cyclomatic complexity
|
/// exhaustive switch: no `default`, so adding a `TokenType` case is a
|
||||||
/// under the project's lint limit; the split carries no meaning beyond
|
/// compile error here instead of a runtime trap. The lint's complexity
|
||||||
/// that; each `default:` either forwards to the next initializer (the
|
/// metric ignores case statements precisely for closed-enum mappings
|
||||||
/// cases it doesn't itself handle) or, in the last one, is truly
|
/// like this one.
|
||||||
/// unreachable because the first two together already handle every
|
|
||||||
/// non-payload-bearing case.
|
|
||||||
init(_ type: PureYAML.Parsing.LibYAML.TokenType) {
|
init(_ type: PureYAML.Parsing.LibYAML.TokenType) {
|
||||||
switch type {
|
switch type {
|
||||||
case .streamStart: self = .streamStart
|
case .streamStart: self = .streamStart
|
||||||
@ -73,12 +71,6 @@ extension PureYAML.Streaming.Token.Kind {
|
|||||||
case .blockMappingStart: self = .blockMappingStart
|
case .blockMappingStart: self = .blockMappingStart
|
||||||
case .blockEnd: self = .blockEnd
|
case .blockEnd: self = .blockEnd
|
||||||
case .blockEntry: self = .blockEntry
|
case .blockEntry: self = .blockEntry
|
||||||
default: self = Self(structural: type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(structural type: PureYAML.Parsing.LibYAML.TokenType) {
|
|
||||||
switch type {
|
|
||||||
case .flowSequenceStart: self = .flowSequenceStart
|
case .flowSequenceStart: self = .flowSequenceStart
|
||||||
case .flowMappingStart: self = .flowMappingStart
|
case .flowMappingStart: self = .flowMappingStart
|
||||||
case .flowSequenceEnd: self = .flowSequenceEnd
|
case .flowSequenceEnd: self = .flowSequenceEnd
|
||||||
@ -87,19 +79,12 @@ extension PureYAML.Streaming.Token.Kind {
|
|||||||
case .key: self = .key
|
case .key: self = .key
|
||||||
case .value: self = .value
|
case .value: self = .value
|
||||||
case .reservedDirective: self = .reservedDirective
|
case .reservedDirective: self = .reservedDirective
|
||||||
default: self = Self(payload: type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private init(payload type: PureYAML.Parsing.LibYAML.TokenType) {
|
|
||||||
switch type {
|
|
||||||
case let .versionDirective(major, minor): self = .versionDirective(major: major, minor: minor)
|
case let .versionDirective(major, minor): self = .versionDirective(major: major, minor: minor)
|
||||||
case let .tagDirective(handle, prefix): self = .tagDirective(handle: handle, prefix: prefix)
|
case let .tagDirective(handle, prefix): self = .tagDirective(handle: handle, prefix: prefix)
|
||||||
case let .anchor(name): self = .anchor(name: name)
|
case let .anchor(name): self = .anchor(name: name)
|
||||||
case let .alias(name): self = .alias(name: name)
|
case let .alias(name): self = .alias(name: name)
|
||||||
case let .tag(handle, suffix): self = .tag(handle: handle, suffix: suffix)
|
case let .tag(handle, suffix): self = .tag(handle: handle, suffix: suffix)
|
||||||
case let .scalar(value, style): self = .scalar(value: value, style: PureYAML.Streaming.Token.ScalarStyle(style))
|
case let .scalar(value, style): self = .scalar(value: value, style: PureYAML.Streaming.Token.ScalarStyle(style))
|
||||||
default: preconditionFailure("unreachable: init(_:) and init(structural:) handle every non-payload TokenType case")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user