Skip to content
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

FromUnicodeScalarView deprecation message possibly references unimplemented conversion? #344

Open
kamcma opened this issue Apr 2, 2024 · 4 comments

Comments

@kamcma
Copy link
Contributor

kamcma commented Apr 2, 2024

I think the deprecation messages for FromUnicodeScalarView might reference an unimplemented conversion?

@available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.")
public struct FromUnicodeScalarView<Input, UnicodeScalarsParser: Parser>: Parser
where UnicodeScalarsParser.Input == Substring.UnicodeScalarView {
public let unicodeScalarsParser: UnicodeScalarsParser
public let toUnicodeScalars: (Input) -> Substring.UnicodeScalarView
public let fromUnicodeScalars: (Substring.UnicodeScalarView) -> Input
@inlinable
public func parse(_ input: inout Input) rethrows -> UnicodeScalarsParser.Output {
var unicodeScalars = self.toUnicodeScalars(input)
defer { input = self.fromUnicodeScalars(unicodeScalars) }
return try self.unicodeScalarsParser.parse(&unicodeScalars)
}
}
@available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.")
extension FromUnicodeScalarView where Input == ArraySlice<UInt8> {
@inlinable
public init(@ParserBuilder<Substring.UnicodeScalarView> _ build: () -> UnicodeScalarsParser) {
self.unicodeScalarsParser = build()
self.toUnicodeScalars = { Substring(decoding: $0, as: UTF8.self).unicodeScalars }
self.fromUnicodeScalars = { ArraySlice(Substring($0).utf8) }
}
}
@available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.")
extension FromUnicodeScalarView where Input == Substring {
@inlinable
public init(@ParserBuilder<Substring.UnicodeScalarView> _ build: () -> UnicodeScalarsParser) {
self.unicodeScalarsParser = build()
self.toUnicodeScalars = \.unicodeScalars
self.fromUnicodeScalars = Substring.init
}
}
@available(*, deprecated, message: "Use 'From(.unicodeScalars)' instead.")
extension FromUnicodeScalarView where Input == Substring.UTF8View {
@inlinable
public init(@ParserBuilder<Substring.UnicodeScalarView> _ build: () -> UnicodeScalarsParser) {
self.unicodeScalarsParser = build()
self.toUnicodeScalars = { Substring($0).unicodeScalars }
self.fromUnicodeScalars = { Substring($0).utf8 }
}

This compiles with the deprecation warning:

let foo: some Parser<Substring.UTF8View, Void> = FromUnicodeScalarView { // ⚠️ 'FromUnicodeScalarView' is deprecated: Use 'From(.unicodeScalars)' instead.
  Peek {
    Prefix(1, while: CharacterSet.alphanumerics.contains)
  }
}

But the suggested replacement does not:

let bar: some Parser<Substring.UTF8View, Void> = From(.unicodeScalars) { // 🛑 Type 'Conversion' has no member 'unicodeScalars'
  Peek {
    Prefix(1, while: CharacterSet.alphanumerics.contains)
  }
}

Would be happy to be told I'm holding it wrong! Feel free to close/convert to discussion if so. Thanks for the incredible library.

@stephencelis
Copy link
Member

@kamcma I think that missing conversion is just an oversight. Wanna PR one?

@kamcma
Copy link
Contributor Author

kamcma commented Apr 5, 2024

Will do!

@kamcma
Copy link
Contributor Author

kamcma commented Apr 5, 2024

For the record, the motivating use-case that led me to even discover the absence of these conversions mentioned in the deprecation message was wanting to use Foundation's CharacterSet.contains(_:), which operates on Unicode.Scalars, as the predicate for the Prefix(_ length:while:). Eg:

let p = Parse(input: Substring.self) {
  Peek {
    From(.unicodeScalars) {
      Prefix(1, while: CharacterSet.alphanumerics.contains)
    }
  }
  // ...
}

If there's a better way to do that, I'm all ears.

@kamcma
Copy link
Contributor Author

kamcma commented Apr 11, 2024

Well, having played around with CharacterSet as a parser directly a little more, I may be able to accomplish this more cleanly like so:

let p = Parse(input: Substring.self) {
  Peek {
    Prefix(1).pipe {
      CharacterSet.letters
    }
  }
  CharacterSet.alphanumerics
}

Probably FromUnicodeScalarView's deprecation message still shouldn't reference an unimplemented conversion, but I may no longer need that particular conversion myself (Substring/Substring.UTF8View/ArraySlice<UInt8> to Substring.UnicodeScalars). So feel free to re-evaluate if it's a conversion you want the library to offer, and close the issue/PR if not.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants