1- using Dahomey . Cbor . Util ;
1+ using Dahomey . Cbor . Serialization . Converters ;
2+ using Dahomey . Cbor . Serialization . Converters . Mappings ;
3+ using Dahomey . Cbor . Util ;
24using System ;
35using System . Collections . Concurrent ;
4- using System . Reflection ;
5- using System . Text ;
66
77namespace Dahomey . Cbor . Serialization . Conventions
88{
9- public class DefaultDiscriminatorConvention : IDiscriminatorConvention
9+ public class DefaultDiscriminatorConvention < T > : IDiscriminatorConvention
10+ where T : notnull
1011 {
1112 private readonly SerializationRegistry _serializationRegistry ;
1213 private readonly ReadOnlyMemory < byte > _memberName ;
13- private readonly ConcurrentDictionary < string , Type > _typesByDiscriminator = new ConcurrentDictionary < string , Type > ( ) ;
14- private readonly ConcurrentDictionary < Type , string > _discriminatorsByType = new ConcurrentDictionary < Type , string > ( ) ;
14+ private readonly ConcurrentDictionary < T , Type > _typesByDiscriminator = new ( ) ;
15+ private readonly ConcurrentDictionary < Type , T > _discriminatorsByType = new ( ) ;
16+ private readonly ICborConverter < T > _converter ;
1517
1618 public ReadOnlySpan < byte > MemberName => _memberName . Span ;
1719
@@ -24,69 +26,49 @@ public DefaultDiscriminatorConvention(SerializationRegistry serializationRegistr
2426 {
2527 _serializationRegistry = serializationRegistry ;
2628 _memberName = memberName . AsBinaryMemory ( ) ;
29+ _converter = serializationRegistry . ConverterRegistry . Lookup < T > ( ) ;
2730 }
2831
2932
3033 public bool TryRegisterType ( Type type )
3134 {
35+ IObjectMapping objectMapping = _serializationRegistry . ObjectMappingRegistry . Lookup ( type ) ;
36+
37+ if ( objectMapping . Discriminator == null || objectMapping . Discriminator is not T discriminator )
38+ {
39+ return false ;
40+ }
41+
42+ _discriminatorsByType . TryAdd ( type , discriminator ) ;
43+ _typesByDiscriminator . TryAdd ( discriminator , type ) ;
3244 return true ;
3345 }
3446
3547 public Type ReadDiscriminator ( ref CborReader reader )
3648 {
37- string ? discriminator = reader . ReadString ( ) ;
49+ T discriminator = _converter . Read ( ref reader ) ;
3850
3951 if ( discriminator == null )
4052 {
41- throw reader . BuildException ( "Discrimnator cannot be null or empty" ) ;
53+ throw new CborException ( "Null discriminator" ) ;
54+ }
55+
56+ if ( ! _typesByDiscriminator . TryGetValue ( discriminator , out Type ? type ) )
57+ {
58+ throw new CborException ( $ "Unknown type discriminator: { discriminator } ") ;
4259 }
4360
44- Type type = _typesByDiscriminator . GetOrAdd ( discriminator , NameToType ) ;
4561 return type ;
4662 }
4763
4864 public void WriteDiscriminator ( ref CborWriter writer , Type actualType )
4965 {
50- string discriminator = _discriminatorsByType . GetOrAdd ( actualType , TypeToName ) ;
51- writer . WriteString ( discriminator ) ;
52- }
53-
54- private string TypeToName ( Type type )
55- {
56- return type . FullName + ", " + type . Assembly . GetName ( ) . Name ;
57- }
58-
59- private Type NameToType ( string name )
60- {
61- string [ ] parts = name . Split ( new [ ] { ',' , ' ' } , StringSplitOptions . RemoveEmptyEntries ) ;
62-
63- string ? assemblyName ;
64- string typeName ;
65-
66- switch ( parts . Length )
67- {
68- case 1 :
69- typeName = parts [ 0 ] ;
70- assemblyName = null ;
71- break ;
72-
73- case 2 :
74- typeName = parts [ 0 ] ;
75- assemblyName = parts [ 1 ] ;
76- break ;
77-
78- default :
79- throw new CborException ( $ "Invalid discriminator { name } ") ;
80-
81- }
82-
83- if ( ! string . IsNullOrEmpty ( assemblyName ) )
66+ if ( ! _discriminatorsByType . TryGetValue ( actualType , out T ? discriminator ) )
8467 {
85- Assembly assembly = Assembly . Load ( assemblyName ) ;
86- return assembly . GetType ( typeName ) ?? throw new CborException ( $ "Cannot get type from { name } ") ;
68+ throw new CborException ( $ "Unknown discriminator for type: { actualType } ") ;
8769 }
8870
89- return Type . GetType ( typeName ) ?? throw new CborException ( $ "Cannot get type from { name } " ) ;
71+ _converter . Write ( ref writer , discriminator ) ;
9072 }
9173 }
9274}
0 commit comments