Skip to content

Commit

Permalink
Refactor variable expansion
Browse files Browse the repository at this point in the history
This change eliminates a swiftlint cyclomatic_complexity issue
  • Loading branch information
alexdeem committed Jun 10, 2024
1 parent c63916d commit c40686d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 27 deletions.
24 changes: 1 addition & 23 deletions Sources/ScreamURITemplate/Internal/Components.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,36 +64,14 @@ struct ExpressionComponent: Component {
self.templatePosition = templatePosition
}

// swiftlint:disable:next cyclomatic_complexity
func expand(variables: VariableProvider) throws -> String {
let configuration = expressionOperator.expansionConfiguration()
let expansions = try variableList.compactMap { variableSpec -> String? in
guard let value = variables[String(variableSpec.name)]?.asTypedVariableValue() else {
return nil
}
do {
switch value {
case let .string(plainValue):
return try plainValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case let .list(arrayValue):
switch variableSpec.modifier {
case .prefix:
throw FormatError.failure(reason: "Prefix operator can only be applied to string")
case .explode:
return try arrayValue.explodeForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case .none:
return try arrayValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
}
case let .associativeArray(associativeArrayValue):
switch variableSpec.modifier {
case .prefix:
throw FormatError.failure(reason: "Prefix operator can only be applied to string")
case .explode:
return try associativeArrayValue.explodeForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case .none:
return try associativeArrayValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
}
}
return try value.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
} catch let FormatError.failure(reason) {
throw URITemplate.Error.expansionFailure(position: templatePosition, reason: "Failed expanding variable \"\(variableSpec.name)\": \(reason)")
}
Expand Down
35 changes: 31 additions & 4 deletions Sources/ScreamURITemplate/Internal/ValueFormatting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,34 @@ enum FormatError: Error {
case failure(reason: String)
}

func percentEncode(string: String, withAllowedCharacters allowedCharacterSet: CharacterSet, allowPercentEncodedTriplets: Bool) throws -> String {
extension TypedVariableValue {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration configuration: ExpansionConfiguration) throws -> String? {
switch self {
case let .string(plainValue):
return try plainValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case let .list(arrayValue):
switch variableSpec.modifier {
case .prefix:
throw FormatError.failure(reason: "Prefix operator can only be applied to string")
case .explode:
return try arrayValue.explodeForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case .none:
return try arrayValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
}
case let .associativeArray(associativeArrayValue):
switch variableSpec.modifier {
case .prefix:
throw FormatError.failure(reason: "Prefix operator can only be applied to string")
case .explode:
return try associativeArrayValue.explodeForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
case .none:
return try associativeArrayValue.formatForTemplateExpansion(variableSpec: variableSpec, expansionConfiguration: configuration)
}
}
}
}

private func percentEncode(string: String, withAllowedCharacters allowedCharacterSet: CharacterSet, allowPercentEncodedTriplets: Bool) throws -> String {
guard var encoded = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) else {
throw FormatError.failure(reason: "Percent Encoding Failed")
}
Expand All @@ -45,7 +72,7 @@ func percentEncode(string: String, withAllowedCharacters allowedCharacterSet: Ch
return encoded
}

extension StringProtocol {
private extension StringProtocol {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String {
let modifiedValue = if let prefixLength = variableSpec.prefixLength() {
String(prefix(prefixLength))
Expand All @@ -63,7 +90,7 @@ extension StringProtocol {
}
}

extension Array where Element: StringProtocol {
private extension Array where Element: StringProtocol {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let separator = ","
let encodedExpansions = try map { element -> String in
Expand Down Expand Up @@ -101,7 +128,7 @@ extension Array where Element: StringProtocol {
}
}

extension [TypedVariableValue.AssociativeArrayElement] {
private extension [TypedVariableValue.AssociativeArrayElement] {
func formatForTemplateExpansion(variableSpec: VariableSpec, expansionConfiguration: ExpansionConfiguration) throws -> String? {
let encodedExpansions = try map { key, value -> String in
let encodedKey = try percentEncode(string: String(key), withAllowedCharacters: expansionConfiguration.percentEncodingAllowedCharacterSet, allowPercentEncodedTriplets: expansionConfiguration.allowPercentEncodedTriplets)
Expand Down

0 comments on commit c40686d

Please sign in to comment.