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:
Mihaela Mihaljevic 2026-07-12 13:26:06 +02:00
parent b48a30f978
commit 20f080a9f7
2 changed files with 10 additions and 20 deletions

View File

@ -14,5 +14,10 @@ force_cast: error
line_length:
warning: 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:
mandatory_comma: true

View File

@ -56,13 +56,11 @@ extension PureYAML.Streaming.Token {
}
extension PureYAML.Streaming.Token.Kind {
/// A mechanical 1:1 mapping over all 22 `TokenType` cases, split across
/// three initializers purely to keep each switch's cyclomatic complexity
/// under the project's lint limit; the split carries no meaning beyond
/// that; each `default:` either forwards to the next initializer (the
/// cases it doesn't itself handle) or, in the last one, is truly
/// unreachable because the first two together already handle every
/// non-payload-bearing case.
/// A mechanical 1:1 mapping over all 22 `TokenType` cases in one
/// exhaustive switch: no `default`, so adding a `TokenType` case is a
/// compile error here instead of a runtime trap. The lint's complexity
/// metric ignores case statements precisely for closed-enum mappings
/// like this one.
init(_ type: PureYAML.Parsing.LibYAML.TokenType) {
switch type {
case .streamStart: self = .streamStart
@ -73,12 +71,6 @@ extension PureYAML.Streaming.Token.Kind {
case .blockMappingStart: self = .blockMappingStart
case .blockEnd: self = .blockEnd
case .blockEntry: self = .blockEntry
default: self = Self(structural: type)
}
}
private init(structural type: PureYAML.Parsing.LibYAML.TokenType) {
switch type {
case .flowSequenceStart: self = .flowSequenceStart
case .flowMappingStart: self = .flowMappingStart
case .flowSequenceEnd: self = .flowSequenceEnd
@ -87,19 +79,12 @@ extension PureYAML.Streaming.Token.Kind {
case .key: self = .key
case .value: self = .value
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 .tagDirective(handle, prefix): self = .tagDirective(handle: handle, prefix: prefix)
case let .anchor(name): self = .anchor(name: name)
case let .alias(name): self = .alias(name: name)
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))
default: preconditionFailure("unreachable: init(_:) and init(structural:) handle every non-payload TokenType case")
}
}
}