@@ -642,6 +642,59 @@ class RegexDSLTests: XCTestCase {
642642 }
643643 }
644644 }
645+
646+ func testSemanticVersionExample( ) {
647+ struct SemanticVersion : Equatable {
648+ var major : Int
649+ var minor : Int
650+ var patch : Int
651+ var dev : String ?
652+ }
653+ struct SemanticVersionParser : CustomRegexComponent {
654+ typealias Match = SemanticVersion
655+ func match(
656+ _ input: String ,
657+ startingAt index: String . Index ,
658+ in bounds: Range < String . Index >
659+ ) -> ( upperBound: String . Index , match: SemanticVersion ) ? {
660+ let regex = Regex {
661+ tryCapture ( oneOrMore ( . digit) ) { Int ( $0) }
662+ " . "
663+ tryCapture ( oneOrMore ( . digit) ) { Int ( $0) }
664+ optionally {
665+ " . "
666+ tryCapture ( oneOrMore ( . digit) ) { Int ( $0) }
667+ }
668+ optionally {
669+ " - "
670+ capture ( oneOrMore ( . word) )
671+ }
672+ }
673+
674+ guard let match = input [ index..< bounds. upperBound] . firstMatch ( of: regex) ,
675+ match. range. lowerBound == index
676+ else { return nil }
677+
678+ let result = SemanticVersion (
679+ major: match. result. 1 ,
680+ minor: match. result. 2 ,
681+ patch: match. result. 3 ?? 0 ,
682+ dev: match. result. 4 . map ( String . init) )
683+ return ( match. range. upperBound, result)
684+ }
685+ }
686+
687+ let versions = [
688+ ( " 1.0 " , SemanticVersion ( major: 1 , minor: 0 , patch: 0 ) ) ,
689+ ( " 1.0.1 " , SemanticVersion ( major: 1 , minor: 0 , patch: 1 ) ) ,
690+ ( " 12.100.5-dev " , SemanticVersion ( major: 12 , minor: 100 , patch: 5 , dev: " dev " ) ) ,
691+ ]
692+
693+ let parser = SemanticVersionParser ( )
694+ for (str, version) in versions {
695+ XCTAssertEqual ( str. match ( parser) ? . match, version)
696+ }
697+ }
645698}
646699
647700extension Unicode . Scalar {
0 commit comments