@@ -642,6 +642,59 @@ class RegexDSLTests: XCTestCase {
642
642
}
643
643
}
644
644
}
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
+ }
645
698
}
646
699
647
700
extension Unicode . Scalar {
0 commit comments