|
| 1 | +using System; |
1 | 2 | using System.Collections.Generic; |
| 3 | +using System.Linq; |
2 | 4 | using System.Runtime.CompilerServices; |
| 5 | +using System.Runtime.InteropServices; |
3 | 6 | using Amazon.DynamoDBv2.Model; |
4 | 7 | using DynamoDBGenerator.Internal; |
5 | 8 |
|
6 | 9 | namespace DynamoDBGenerator.Converters.Internal; |
7 | 10 |
|
8 | | -internal sealed class StringSetConverter : |
| 11 | +internal sealed class NoneNullableStringSetConverter : |
9 | 12 | IReferenceTypeConverter<IReadOnlySet<string>>, |
10 | 13 | IReferenceTypeConverter<HashSet<string>>, |
11 | 14 | IReferenceTypeConverter<ISet<string>>, |
12 | 15 | IReferenceTypeConverter<SortedSet<string>>, |
13 | | - IStaticSingleton<StringSetConverter> |
| 16 | + IStaticSingleton<NoneNullableStringSetConverter> |
14 | 17 | { |
15 | 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
16 | | - private static HashSet<string>? ToHashSet(AttributeValue attributeValue) |
| 19 | + private static TSet? ToSet<TSet>( |
| 20 | + AttributeValue attributeValue, |
| 21 | + Func<int, TSet> factory |
| 22 | + ) |
| 23 | + where TSet : class, ISet<string> |
17 | 24 | { |
18 | | - return attributeValue.IsSSSet |
19 | | - ? new HashSet<string>(attributeValue.SS) |
20 | | - : null; |
| 25 | + if (attributeValue.IsSSSet is false) |
| 26 | + return null; |
| 27 | + |
| 28 | + var span = CollectionsMarshal.AsSpan(attributeValue.SS); |
| 29 | + var set = factory(span.Length); |
| 30 | + foreach (var item in span) |
| 31 | + { |
| 32 | + if (item is null) |
| 33 | + throw ExceptionHelper.NotNull(null); |
| 34 | + |
| 35 | + set.Add(item); |
| 36 | + } |
| 37 | + |
| 38 | + return set; |
21 | 39 | } |
22 | 40 |
|
23 | 41 | [MethodImpl(MethodImplOptions.AggressiveInlining)] |
24 | 42 | private static AttributeValue ToAttributeValue(IEnumerable<string> enumerable) |
25 | 43 | { |
26 | | - return new AttributeValue { SS = new List<string>(enumerable) }; |
| 44 | + var ss = enumerable.TryGetNonEnumeratedCount(out var count) |
| 45 | + ? new List<string>(capacity: count) |
| 46 | + : new List<string>(); |
| 47 | + |
| 48 | + foreach (var item in enumerable) |
| 49 | + { |
| 50 | + if (item is null) // TODO need datamember |
| 51 | + throw ExceptionHelper.NotNull(null); |
| 52 | + |
| 53 | + ss.Add(item); |
| 54 | + } |
| 55 | + |
| 56 | + return new AttributeValue { SS = ss }; |
27 | 57 | } |
28 | 58 |
|
29 | 59 | IReadOnlySet<string>? IReferenceTypeConverter<IReadOnlySet<string>>.Read(AttributeValue attributeValue) |
30 | 60 | { |
31 | | - return ToHashSet(attributeValue); |
| 61 | + return ToSet(attributeValue, x => new HashSet<string>(x)); |
32 | 62 | } |
33 | 63 |
|
34 | 64 | ISet<string>? IReferenceTypeConverter<ISet<string>>.Read(AttributeValue attributeValue) |
35 | 65 | { |
36 | | - return ToHashSet(attributeValue); |
| 66 | + return ToSet(attributeValue, x => new HashSet<string>(x)); |
37 | 67 | } |
38 | 68 |
|
39 | 69 | HashSet<string>? IReferenceTypeConverter<HashSet<string>>.Read(AttributeValue attributeValue) |
40 | 70 | { |
41 | | - return ToHashSet(attributeValue); |
| 71 | + return ToSet(attributeValue, x => new HashSet<string>(x)); |
42 | 72 | } |
43 | 73 |
|
44 | 74 | SortedSet<string>? IReferenceTypeConverter<SortedSet<string>>.Read(AttributeValue attributeValue) |
45 | 75 | { |
46 | | - return attributeValue.IsSSSet |
47 | | - ? new SortedSet<string>(attributeValue.SS) |
48 | | - : null; |
| 76 | + return ToSet(attributeValue, _ => new SortedSet<string>()); |
49 | 77 | } |
50 | 78 |
|
51 | 79 | AttributeValue IReferenceTypeConverter<SortedSet<string>>.Write(SortedSet<string> element) |
|
0 commit comments