swift-foundation icon indicating copy to clipboard operation
swift-foundation copied to clipboard

It would be nice if there is a parser for UUIDs that could be used with the Swift Regex API.

Open itingliu opened this issue 4 months ago • 8 comments

This would be something like the initializer

    /// Create a UUID from a string such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F".
    ///
    /// Returns nil for invalid strings.
    public init?(uuidString string: String)

But works with Regex or RegexComponents so it can work with capture and transform out of the box, like Date.ISO8601FormatStyle supports.

itingliu avatar Aug 13 '25 21:08 itingliu

Hi! I have been developing this enhancement, but when compiling, I encounter an issue that I have been working on but have not yet resolved. I can make a pull request so they can review my implementation. Here are the details:

Compiler issue encountered and fix

  • Error seen: Initializer 'init(_:transform:)' requires the types 'UUID' and '(Substring, UUID)' be equivalent
  • Cause:
    • The transform parameter of TryCapture must match the output shape of the inner component.
    • When the parser was placed in a RegexComponent where Self == UUID context or when an inner Capture was used, composing the component changed the output shape to a tuple like (Substring, UUID). The transform was written to accept a plain Substring, so the types didn't match and the compiler rejected the initializer.
  • Fix applied:
    • Move the parser out of the RegexComponent-constrained extension into a plain extension UUID so the inner pattern produces a plain Substring.
    • Use TryCapture directly on the raw pattern (do not wrap the pattern in Capture) so the transform receives a Substring -> UUID?.
    • Example implementation:
      // filepath: Sources/FoundationEssentials/UUID.swift
      extension UUID {
          public static var uuidParser: some RegexComponent<UUID> {
              TryCapture {
                  Repeat(count: 8) { .hexDigit }
                  "-"
                  Repeat(count: 4) { .hexDigit }
                  "-"
                  Repeat(count: 4) { .hexDigit }
                  "-"
                  Repeat(count: 4) { .hexDigit }
                  "-"
                  Repeat(count: 12) { .hexDigit }
              } transform: { (match: Substring) -> UUID? in
                  UUID(uuidString: String(match))
              }
          }
      }
      

beltradini avatar Aug 14 '25 20:08 beltradini

@beltradini Hey thanks for taking a look!

Your solution and diagnose to this particular error looks reasonable to me, but I'm not super sure how this is related to the feature this issue is asking. So yes, if you don't mind creating a PR we can all follow along and debug together!

itingliu avatar Aug 15 '25 18:08 itingliu

@itingliu That sounds like a great idea!

Thanks for your comment. I’ll get the pull request ready with details so we can review it and figure it out together!

beltradini avatar Aug 17 '25 01:08 beltradini

@beltradini did you make any progress on your proposed change?

parkera avatar Oct 14 '25 17:10 parkera

@parkera Yes! Just submitted the implementation to a branch

Added UUID.parser, UUID.caseInsensitiveParser, and UUID: RegexComponent conformance with test coverage

Haven't verified tests pass yet (build time constraints), so will need CI validation. Also realized both parsers may be functionally identical since .hexDigit is already case-insensitive.

Before finalizing the PR: should I consolidate to a single parser API, or is there value in keeping both for clarity? Are there other Foundation regex parsers I should reference for consistency?

beltradini avatar Oct 15 '25 00:10 beltradini

#1547 Here is my contribution. I hope it helps with this enhancement and that we can work together to improve it!

beltradini avatar Oct 15 '25 00:10 beltradini

We will still need an API proposal for this since it's adding new API even though it's very small. @beltradini would you be up to drafting up a proposal too?

itingliu avatar Oct 16 '25 15:10 itingliu

Of course, I can draft a proposal for the API. You can count on it. I'll be working on the idea @itingliu

beltradini avatar Oct 16 '25 20:10 beltradini