-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add example support. #10
Conversation
- Adds `example` support to schema properties. - Adds support for `x-example` on parameter definitions. - Adds an `other(String)` type to `StringFormat`.
# Conflicts: # Sources/Metadata.swift # Tests/SwaggerParserTests/SwaggerParserTests.swift
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some suggestions about how I think we could clean up StringFormat while adding the new functionality you suggested.
Sources/Enums.swift
Outdated
public enum StringFormat: String { | ||
public enum StringFormat: RawRepresentable { | ||
|
||
public typealias RawValue = String | ||
|
||
/// Base64 encoded characters | ||
case byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add the following options, per the JSON Schema spec:
"date-time": Date representation, as defined by RFC 3339, section 5.6.
"email": Internet email address, see RFC 5322, section 3.4.1.
"hostname": Internet host name, see RFC 1034, section 3.1.
"ipv4": IPv4 address, according to dotted-quad ABNF syntax as defined in RFC 2673, section 3.2.
"ipv6": IPv6 address, as defined in RFC 2373, section 2.2.
"uri": A universal resource identifier (URI), according to RFC3986.
As well as our added byte, binary, url and other options.
Sources/Enums.swift
Outdated
@@ -1,6 +1,8 @@ | |||
import Foundation | |||
|
|||
public enum StringFormat: String { | |||
public enum StringFormat: RawRepresentable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we move StringFormat into its own file, StringFormat.swift
} | ||
|
||
guard | ||
let aStringFormat = aStringOptionalFormat, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about anOptionalStringFormat
Oh I don't know how it lost my comment, but I suggested defining a nested, private, RawStringFormat enum which is strongly-typed instead of defining a bunch of private static raw value strings @n8chur |
} | ||
} | ||
|
||
private enum RawStringFormat: String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks Good :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good - just added a few more comments.
Sources/StringFormat.swift
Outdated
/// A universal resource identifier (URI), according to RFC3986. | ||
case uri | ||
|
||
public init(rawValue: RawValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you've typealiased RawValue = String, you can use String everywhere else in the type.
Sources/StringFormat.swift
Outdated
|
||
public var rawValue: RawValue { | ||
switch self { | ||
case .byte: return RawStringFormat.byte.rawValue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making a private function that returns the raw string format optionally? E.g.:
private func rawStringFormat() -> RawStringFormat? {
switch self {
case .byte: return .byte
case .binary: return .binary
case .date: return .date
case .dateTime: return .dateTime
case .email: return .email
case .hostname: return .hostname
case .ipv4: return .ipv4
case .ipv6: return .ipv6
case .password: return .password
case .uri: return .uri
case .other: return nil
}
}
public var rawValue: String {
if let rawValue = self.rawStringValue() {
return rawValue
} else if case .other(let rawValue) = self {
return rawValue
} else {
assertionFailure()
return ""
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had something similar at first, but ended up going with the approach found in this revision to avoid the fatalError()
branch (which, although it should never be hit, needs to exist). I agree that it does clean up the rawValue
implementation and makes the mapping easier to read, but I'm not sure that it's worth introducing the failure case for.
Would you prefer that I take the approach that you recommended or do you think avoiding the failure case is preferable? Do you have an alternate suggestion that doesn't involve a branch that results in a fatalError()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, you can see that the assertion failure can never be hit here. The raw value will only be nil if self == .other, in which case the else if case will be hit. The assertion failure is to prevent someone from adding another case and not handling it in the future, and assertions don't trigger in prod builds.
Sources/StringFormat.swift
Outdated
return | ||
} | ||
|
||
self = rawStringFormat.stringFormat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function can be reduced to:
public init(rawValue: String) {
self = RawStringFormat(rawValue: rawValue)?.stringFormat ?? .other(rawValue)
}
|
||
init(map: Map) throws { | ||
name = try map.value("name") | ||
location = try map.value("in") | ||
description = try? map.value("description") | ||
required = (try? map.value("required")) ?? false | ||
example = try? map.value("x-example") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the field name x-example here but example in Metadata?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example
is not a documented key for parameter. "body" parameters can have a schema
which could have an example
, but non-"body" parameters do not have an example
key. Here's a link to the spec where it discusses parameters.
In order to introduce this feature on all parameter types, I added support for x-example
to allow specs utilizing the feature to remain valid Swagger OpenAPI 2.0 specs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, sure. Thanks
Also please rebase this off of master now that your other changes are merged. To prevent us from having repeated merge conflicts in our tests files, can we break up the tests into multiple files based on the subject they're testing? |
# Conflicts: # Tests/SwaggerParserTests/SwaggerParserTests.swift
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for doing this! It looks great :)
|
||
init(map: Map) throws { | ||
name = try map.value("name") | ||
location = try map.value("in") | ||
description = try? map.value("description") | ||
required = (try? map.value("required")) ?? false | ||
example = try? map.value("x-example") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, sure. Thanks
example
support to schema properties.x-example
on parameter definitions.other(String)
type toStringFormat
.