@@ -72,93 +72,28 @@ private static bool ReplaceSubstitutions(
7272 var spanMatch = span . Slice ( match . Index , match . Length ) ;
7373 var fullKey = spanMatch . Trim ( [ '{' , '}' ] ) ;
7474
75- // Handle mutation operators (same logic as SubstitutionParser)
76- var components = fullKey . ToString ( ) . Split ( '|' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
77- var key = components . Length > 1 ? components [ 0 ] . Trim ( ) : fullKey . ToString ( ) ;
75+ // Enhanced mutation support: parse key and mutations using shared utility
76+ var ( cleanKey , mutations ) = SubstitutionMutationHelper . ParseKeyWithMutations ( fullKey . ToString ( ) ) ;
77+
7878 foreach ( var lookup in lookups )
7979 {
80- if ( ! lookup . TryGetValue ( key , out var value ) )
81- continue ;
82-
83- collector ? . CollectUsedSubstitutionKey ( key ) ;
84-
85- // Apply mutations if present
86- if ( components . Length > 1 )
80+ if ( lookup . TryGetValue ( cleanKey , out var value ) )
8781 {
88- value = ApplyMutationsUsingExistingSystem ( value , components [ 1 ..] ) ;
89- }
82+ // Apply mutations if present using shared utility
83+ if ( mutations . Length > 0 )
84+ {
85+ value = SubstitutionMutationHelper . ApplyMutations ( value , mutations ) ;
86+ }
9087
91- replacement ??= span . ToString ( ) ;
92- replacement = replacement . Replace ( spanMatch . ToString ( ) , value ) ;
93- replaced = true ;
94- }
95- }
88+ collector ? . CollectUsedSubstitutionKey ( cleanKey ) ;
9689
97- return replaced ;
98- }
99-
100- private static string ApplyMutationsUsingExistingSystem ( string value , string [ ] mutations )
101- {
102- var result = value ;
103- foreach ( var mutationStr in mutations )
104- {
105- var trimmedMutation = mutationStr . Trim ( ) ;
106- if ( SubstitutionMutationExtensions . TryParse ( trimmedMutation , out var mutation , true , true ) )
107- {
108- // Use the same logic as SubstitutionRenderer.Write
109- var ( success , update ) = mutation switch
110- {
111- SubstitutionMutation . MajorComponent => TryGetVersion ( result , v => $ "{ v . Major } ") ,
112- SubstitutionMutation . MajorX => TryGetVersion ( result , v => $ "{ v . Major } .x") ,
113- SubstitutionMutation . MajorMinor => TryGetVersion ( result , v => $ "{ v . Major } .{ v . Minor } ") ,
114- SubstitutionMutation . IncreaseMajor => TryGetVersion ( result , v => $ "{ v . Major + 1 } .0.0") ,
115- SubstitutionMutation . IncreaseMinor => TryGetVersion ( result , v => $ "{ v . Major } .{ v . Minor + 1 } .0") ,
116- SubstitutionMutation . LowerCase => ( true , result . ToLowerInvariant ( ) ) ,
117- SubstitutionMutation . UpperCase => ( true , result . ToUpperInvariant ( ) ) ,
118- SubstitutionMutation . Capitalize => ( true , Capitalize ( result ) ) ,
119- SubstitutionMutation . KebabCase => ( true , ToKebabCase ( result ) ) ,
120- SubstitutionMutation . CamelCase => ( true , ToCamelCase ( result ) ) ,
121- SubstitutionMutation . PascalCase => ( true , ToPascalCase ( result ) ) ,
122- SubstitutionMutation . SnakeCase => ( true , ToSnakeCase ( result ) ) ,
123- SubstitutionMutation . TitleCase => ( true , TitleCase ( result ) ) ,
124- SubstitutionMutation . Trim => ( true , Trim ( result ) ) ,
125- _ => ( false , result )
126- } ;
127- if ( success )
128- {
129- result = update ;
90+ replacement ??= span . ToString ( ) ;
91+ replacement = replacement . Replace ( spanMatch . ToString ( ) , value ) ;
92+ replaced = true ;
13093 }
13194 }
13295 }
133- return result ;
134- }
13596
136- private static ( bool Success , string Result ) TryGetVersion ( string version , Func < SemVersion , string > transform )
137- {
138- if ( ! SemVersion . TryParse ( version , out var v ) && ! SemVersion . TryParse ( version + ".0" , out v ) )
139- return ( false , version ) ;
140- return ( true , transform ( v ) ) ;
97+ return replaced ;
14198 }
142-
143- // These methods match the exact implementation in SubstitutionRenderer
144- private static string Capitalize ( string input ) =>
145- input switch
146- {
147- null => string . Empty ,
148- "" => string . Empty ,
149- _ => string . Concat ( input [ 0 ] . ToString ( ) . ToUpper ( ) , input . AsSpan ( 1 ) )
150- } ;
151-
152- private static string ToKebabCase ( string str ) => JsonNamingPolicy . KebabCaseLower . ConvertName ( str ) . Replace ( " " , string . Empty ) ;
153-
154- private static string ToCamelCase ( string str ) => JsonNamingPolicy . CamelCase . ConvertName ( str ) . Replace ( " " , string . Empty ) ;
155-
156- private static string ToPascalCase ( string str ) => TitleCase ( str ) . Replace ( " " , string . Empty ) ;
157-
158- private static string ToSnakeCase ( string str ) => JsonNamingPolicy . SnakeCaseLower . ConvertName ( str ) . Replace ( " " , string . Empty ) ;
159-
160- private static string TitleCase ( string str ) => System . Globalization . CultureInfo . InvariantCulture . TextInfo . ToTitleCase ( str ) ;
161-
162- private static string Trim ( string str ) =>
163- str . AsSpan ( ) . Trim ( [ '!' , ' ' , '\t ' , '\r ' , '\n ' , '.' , ',' , ')' , '(' , ':' , ';' , '<' , '>' , '[' , ']' ] ) . ToString ( ) ;
16499}
0 commit comments