@@ -31,6 +31,16 @@ protected RespServer(TextWriter output = null)
3131 _commands = BuildCommands ( this ) ;
3232 }
3333
34+ public HashSet < string > GetCommands ( )
35+ {
36+ var set = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
37+ foreach ( var kvp in _commands )
38+ {
39+ set . Add ( kvp . Key . ToString ( ) ) ;
40+ }
41+ return set ;
42+ }
43+
3444 private static Dictionary < CommandBytes , RespCommand > BuildCommands ( RespServer server )
3545 {
3646 static RedisCommandAttribute CheckSignatureAndGetAttribute ( MethodInfo method )
@@ -313,30 +323,37 @@ public virtual void Log(string message)
313323
314324 public static async ValueTask WriteResponseAsync ( RedisClient client , PipeWriter output , TypedRedisValue value , RedisProtocol protocol )
315325 {
316- static void WritePrefix ( PipeWriter ooutput , char pprefix )
326+ static void WritePrefix ( PipeWriter output , char prefix )
317327 {
318- var span = ooutput . GetSpan ( 1 ) ;
319- span [ 0 ] = ( byte ) pprefix ;
320- ooutput . Advance ( 1 ) ;
328+ var span = output . GetSpan ( 1 ) ;
329+ span [ 0 ] = ( byte ) prefix ;
330+ output . Advance ( 1 ) ;
321331 }
322332
323333 if ( value . IsNil ) return ; // not actually a request (i.e. empty/whitespace request)
324334 if ( client != null && client . ShouldSkipResponse ( ) ) return ; // intentionally skipping the result
325- char prefix ;
335+
326336 var type = value . Type ;
327- if ( protocol is RedisProtocol . Resp2 & type is not ResultType . Null ) type = type . ToResp2 ( ) ;
337+ if ( protocol is RedisProtocol . Resp2 & type is not ResultType . Null )
338+ {
339+ if ( type is ResultType . VerbatimString )
340+ {
341+ var s = ( string ) value . AsRedisValue ( ) ;
342+ if ( s is { Length : >= 4 } && s [ 3 ] == ':' )
343+ value = TypedRedisValue . BulkString ( s . Substring ( 4 ) ) ;
344+ }
345+ type = type . ToResp2 ( ) ;
346+ }
328347RetryResp2 :
329348 if ( protocol is RedisProtocol . Resp3 && value . IsNullValueOrArray )
330349 {
331350 output . Write ( "_\r \n "u8 ) ;
332351 }
333352 else
334353 {
354+ char prefix ;
335355 switch ( type )
336356 {
337- case ResultType . Null :
338- output . Write ( "_\r \n "u8 ) ;
339- break ;
340357 case ResultType . Integer :
341358 PhysicalConnection . WriteInteger ( output , ( long ) value . AsRedisValue ( ) ) ;
342359 break ;
@@ -355,30 +372,34 @@ static void WritePrefix(PipeWriter ooutput, char pprefix)
355372 case ResultType . BulkString :
356373 PhysicalConnection . WriteBulkString ( value . AsRedisValue ( ) , output ) ;
357374 break ;
375+ case ResultType . Null :
376+ case ResultType . Push when value . IsNullArray :
377+ case ResultType . Map when value . IsNullArray :
378+ case ResultType . Set when value . IsNullArray :
379+ case ResultType . Attribute when value . IsNullArray :
380+ output . Write ( "_\r \n "u8 ) ;
381+ break ;
382+ case ResultType . Array when value . IsNullArray :
383+ PhysicalConnection . WriteMultiBulkHeader ( output , - 1 , type ) ;
384+ break ;
358385 case ResultType . Push :
359386 case ResultType . Map :
360387 case ResultType . Array :
361- if ( value . IsNullArray )
362- {
363- PhysicalConnection . WriteMultiBulkHeader ( output , - 1 , type ) ;
364- }
365- else
388+ case ResultType . Set :
389+ case ResultType . Attribute :
390+ var segment = value . Segment ;
391+ PhysicalConnection . WriteMultiBulkHeader ( output , segment . Count , type ) ;
392+ var arr = segment . Array ;
393+ int offset = segment . Offset ;
394+ for ( int i = 0 ; i < segment . Count ; i ++ )
366395 {
367- var segment = value . Segment ;
368- PhysicalConnection . WriteMultiBulkHeader ( output , segment . Count , type ) ;
369- var arr = segment . Array ;
370- int offset = segment . Offset ;
371- for ( int i = 0 ; i < segment . Count ; i ++ )
372- {
373- var item = arr [ offset ++ ] ;
374- if ( item . IsNil )
375- throw new InvalidOperationException ( "Array element cannot be nil, index " + i ) ;
376-
377- // note: don't pass client down; this would impact SkipReplies
378- await WriteResponseAsync ( null , output , item , protocol ) ;
379- }
380- }
396+ var item = arr [ offset ++ ] ;
397+ if ( item . IsNil )
398+ throw new InvalidOperationException ( "Array element cannot be nil, index " + i ) ;
381399
400+ // note: don't pass client down; this would impact SkipReplies
401+ await WriteResponseAsync ( null , output , item , protocol ) ;
402+ }
382403 break ;
383404 default :
384405 // retry with RESP2
0 commit comments