33
44using System ;
55using System . Collections . Generic ;
6- using System . Text . RegularExpressions ;
76using Microsoft . OpenApi . Models ;
87using Microsoft . OpenApi . Properties ;
98
@@ -36,7 +35,6 @@ public static class OpenApiPathsRules
3635 }
3736 } ) ;
3837
39- private static readonly Regex regexPath = new Regex ( "\\ {([^/}]+)\\ }" , RegexOptions . Compiled , TimeSpan . FromMilliseconds ( 100 ) ) ;
4038 /// <summary>
4139 /// A relative path to an individual endpoint. The field name MUST begin with a slash.
4240 /// </summary>
@@ -50,7 +48,7 @@ public static class OpenApiPathsRules
5048 {
5149 context . Enter ( path ) ;
5250
53- var pathSignature = regexPath . Replace ( path , "{}" ) ;
51+ var pathSignature = GetPathSignature ( path ) ;
5452
5553 if ( ! hashSet . Add ( pathSignature ) )
5654 context . CreateError ( nameof ( PathMustBeUnique ) ,
@@ -60,6 +58,38 @@ public static class OpenApiPathsRules
6058 }
6159 } ) ;
6260
61+ /// <summary>
62+ /// Replaces placeholders in the path with {}, e.g. /pets/{petId} becomes /pets/{} .
63+ /// </summary>
64+ /// <param name="path">The input path</param>
65+ /// <returns>The path signature</returns>
66+ private static string GetPathSignature ( string path )
67+ {
68+ int i = 0 ;
69+
70+ while ( i < path . Length )
71+ {
72+ int openBrace = path . IndexOf ( '{' , i ) ;
73+
74+ if ( openBrace < 0 )
75+ {
76+ return path ;
77+ }
78+
79+ int closeBrace = path . IndexOf ( '}' , openBrace ) ;
80+
81+ if ( closeBrace < 0 )
82+ {
83+ return path ;
84+ }
85+
86+ path = path . Substring ( 0 , openBrace + 1 ) + path . Substring ( closeBrace , path . Length - closeBrace ) ;
87+ i = openBrace + 2 ;
88+ }
89+
90+ return path ;
91+ }
92+
6393 // add more rules
6494 }
6595}
0 commit comments