@@ -16,6 +16,7 @@ public struct URLPathMacro: PeerMacro {
1616 let name : String
1717 let type : SupportedType
1818 let pathIndex : Int
19+ let caseIndex : Int
1920 }
2021
2122 public static func expansion(
@@ -53,64 +54,64 @@ public struct URLPathMacro: PeerMacro {
5354 return ( name: name, type: supportedType)
5455 } ?? [ ]
5556
56- let patternParams = patternPaths. enumerated ( )
57+ let patternParams : [ PatternParam ] = try patternPaths. enumerated ( )
5758 . filter { index, value in value. isURLPathParam }
58- . map { index , value in
59+ . map { pathIndex , value -> PatternParam in
5960 let name = String ( value. dropFirst ( ) . dropLast ( ) )
61+
62+ guard let ( caseIndex, caseAssociatedType) = caseAssociatedTypes. enumerated ( ) . first ( where: { name == $0. element. name } ) else {
63+ throw URLPatternError ( " URLPath value \" \( name) \" cannot be found in the associated value " )
64+ }
65+
6066 return PatternParam (
61- name: name ,
62- type: caseAssociatedTypes. first ( where: { name == $0. name } ) !. type,
63- pathIndex: index
67+ name: name,
68+ type: caseAssociatedType. type,
69+ pathIndex: pathIndex,
70+ caseIndex: caseIndex
6471 )
6572 }
73+ . sorted ( by: { $0. caseIndex < $1. caseIndex } )
74+
75+ let patternNames = Set ( patternParams. map ( \. name) )
76+ let caseNames = Set ( caseAssociatedTypes. map ( \. name) )
77+
78+ guard patternNames. count == patternParams. count else {
79+ throw URLPatternError ( " The name of an URLPath value cannot be duplicated " )
80+ }
6681
67- if Set ( patternParams . map { $0 . name } ) . count != patternParams . count {
82+ guard caseNames . count == caseAssociatedTypes . count else {
6883 throw URLPatternError ( " The name of an associated value cannot be duplicated " )
6984 }
7085
71- if Set ( patternParams ) . count != caseAssociatedTypes . count {
86+ guard patternNames . count == caseNames . count else {
7287 throw URLPatternError ( " The number of associated values does not match URLPath " )
7388 }
7489
90+ guard patternNames == caseNames else {
91+ throw URLPatternError ( " The name of the URLPath value does not match the associated value " )
92+ }
93+
7594 let staticMethod = try FunctionDeclSyntax ( """
7695 static func \( element. name) (_ url: URL) -> Self? {
77- let inputPaths = url.pathComponents
78- let patternPaths = \( raw: patternPaths)
79-
80- guard isValidURLPaths(inputPaths: inputPaths, patternPaths: patternPaths) else {
81- return nil
82- }
83-
84- \( raw: patternParams. map { param in
96+ let inputPaths = url.pathComponents
97+ let patternPaths = \( raw: patternPaths)
98+
99+ guard isValidURLPaths(inputPaths: inputPaths, patternPaths: patternPaths) else { return nil }
100+ \( raw: patternParams. map { param in
85101 switch param. type {
86- case . Double:
102+ case . Double, . Float , . Int :
87103 """
88- guard let \( param. name) = \( param. type. rawValue) (inputPaths[ \( param. pathIndex) ]) else {
89- return nil
90- }
91- """
92- case . Float:
93- """
94- guard let \( param. name) = \( param. type. rawValue) (inputPaths[ \( param. pathIndex) ]) else {
95- return nil
96- }
97- """
98- case . Int:
99- """
100- guard let \( param. name) = \( param. type. rawValue) (inputPaths[ \( param. pathIndex) ]) else {
101- return nil
102- }
104+ guard let \( param. name) = \( param. type. rawValue) (inputPaths[ \( param. pathIndex) ]) else { return nil }
103105 """
104106 case . String:
105107 """
106108 let \( param. name) = inputPaths[ \( param. pathIndex) ]
107109 """
108110 }
109111 } . joined ( separator: " \n " ) )
110-
111- return \( raw: patternParams. isEmpty
112- ? " . \( element. name. text) "
113- : " . \( element. name. text) ( \( patternParams. map { " \( $0. name) : \( $0. name) " } . joined ( separator: " , " ) ) ) " )
112+ return \( raw: patternParams. isEmpty
113+ ? " . \( element. name. text) "
114+ : " . \( element. name. text) ( \( patternParams. map { " \( $0. name) : \( $0. name) " } . joined ( separator: " , " ) ) ) " )
114115 }
115116 """ )
116117
0 commit comments