11using System ;
2- using System . Buffers ;
32using System . Collections . Generic ;
43using System . Diagnostics . CodeAnalysis ;
54using System . Linq ;
5+ using System . Numerics ;
6+ using System . Runtime . CompilerServices ;
67using Amazon . DynamoDBv2 . Model ;
78using static System . Runtime . InteropServices . CollectionsMarshal ;
89
@@ -22,9 +23,12 @@ public static class MarshallHelper
2223 [ return : NotNullIfNotNull ( nameof ( dict ) ) ]
2324 public static AttributeValue ? ToAttributeValue (
2425 [ NotNullIfNotNull ( nameof ( dict ) ) ] Dictionary < string , AttributeValue > ? dict
25- ) => dict is null
26- ? null
27- : new AttributeValue { M = dict } ;
26+ )
27+ {
28+ return dict is null
29+ ? null
30+ : new AttributeValue { M = dict } ;
31+ }
2832
2933 public static AttributeValue FromDictionary < T , TArgument > (
3034 IEnumerable < KeyValuePair < string , T > > dictionary ,
@@ -45,6 +49,203 @@ public static AttributeValue FromDictionary<T, TArgument>(
4549 return new AttributeValue { M = elements } ;
4650 }
4751
52+ public static AttributeValue FromNullableNumberSet < T > ( IEnumerable < T ? > numbers , string ? _ )
53+ where T : struct , INumber < T >
54+ {
55+ if ( numbers . TryGetNonEnumeratedCount ( out var count ) is false )
56+ return new AttributeValue
57+ {
58+ NS = numbers . Select ( number => number ? . ToString ( ) ) . ToList ( )
59+ } ;
60+
61+ if ( count is 0 )
62+ return new AttributeValue { NS = [ ] } ;
63+
64+ var list = new List < string ? > ( count ) ;
65+ list . AddRange ( numbers . Select ( number => number ? . ToString ( ) ) ) ;
66+
67+ return new AttributeValue { NS = list } ;
68+ }
69+
70+ public static AttributeValue FromNumberSet < T > ( IEnumerable < T > numbers , string ? dataMember )
71+ where T : struct , INumber < T >
72+ {
73+ if ( numbers . TryGetNonEnumeratedCount ( out var count ) is false )
74+ {
75+ var noCapacity = new List < string > ( ) ;
76+
77+ foreach ( var number in numbers )
78+ {
79+ var @string = number . ToString ( ) ;
80+ if ( string . IsNullOrEmpty ( @string ) )
81+ throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ;
82+
83+ noCapacity . Add ( @string ) ;
84+ }
85+
86+ return new AttributeValue { NS = noCapacity } ;
87+ }
88+
89+ if ( count is 0 )
90+ return new AttributeValue { NS = [ ] } ;
91+
92+ var list = new List < string > ( count ) ;
93+
94+ foreach ( var number in numbers )
95+ {
96+ var @string = number . ToString ( ) ;
97+ if ( string . IsNullOrEmpty ( @string ) )
98+ throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ;
99+
100+ list . Add ( @string ) ;
101+ }
102+
103+ return new AttributeValue { NS = list } ;
104+ }
105+
106+ public static AttributeValue FromNullableStringSet ( IEnumerable < string ? > strings , string ? _ )
107+ {
108+ if ( strings . TryGetNonEnumeratedCount ( out var count ) is false )
109+ return new AttributeValue { SS = strings . ToList ( ) } ;
110+
111+ if ( count is 0 )
112+ return new AttributeValue { SS = [ ] } ;
113+
114+ var list = new List < string ? > ( count ) ;
115+ list . AddRange ( strings ) ;
116+
117+ return new AttributeValue { SS = list } ;
118+ }
119+
120+ public static AttributeValue FromStringSet ( IEnumerable < string > strings , string ? dataMember )
121+ {
122+ if ( strings . TryGetNonEnumeratedCount ( out var count ) is false )
123+ {
124+ var list = new List < string > ( ) ;
125+ foreach ( var @string in strings )
126+ {
127+ if ( @string is null )
128+ throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ;
129+ list . Add ( @string ) ;
130+ }
131+
132+ return new AttributeValue { SS = list } ;
133+ }
134+ else
135+ {
136+ if ( count is 0 )
137+ return new AttributeValue { SS = [ ] } ;
138+
139+ var list = new List < string > ( count ) ;
140+
141+ foreach ( var @string in strings )
142+ list . Add ( @string ?? throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ) ;
143+
144+ return new AttributeValue { SS = list } ;
145+ }
146+ }
147+
148+ private static TSet ToNumberSet < TNumber , TSet > (
149+ List < string > numbers ,
150+ Func < int , TSet > factory ,
151+ string ? dataMember
152+ )
153+ where TSet : ICollection < TNumber >
154+ where TNumber : struct , INumber < TNumber >
155+ {
156+ var span = AsSpan ( numbers ) ;
157+ var set = factory ( span . Length ) ;
158+
159+ foreach ( var number in span )
160+ {
161+ if ( number is null )
162+ throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ;
163+
164+ set . Add ( TNumber . Parse ( number , null ) ) ;
165+ }
166+
167+ return set ;
168+ }
169+
170+ private static TSet ToNullableNumberSet < TNumber , TSet > (
171+ List < string ? > numbers ,
172+ Func < int , TSet > factory ,
173+ string ? _
174+ )
175+ where TSet : ICollection < TNumber ? >
176+ where TNumber : struct , INumber < TNumber >
177+ {
178+ var span = AsSpan ( numbers ) ;
179+ var set = factory ( span . Length ) ;
180+
181+ foreach ( var number in span )
182+ {
183+ if ( number is null )
184+ set . Add ( null ) ;
185+ else
186+ set . Add ( TNumber . Parse ( number , null ) ) ;
187+ }
188+
189+ return set ;
190+ }
191+
192+ public static ISet < TNumber > ToNumberISet < TNumber > ( List < string > ns , string ? dataMember )
193+ where TNumber : struct , INumber < TNumber >
194+ {
195+ return ToNumberSet < TNumber , HashSet < TNumber > > ( ns , i => new HashSet < TNumber > ( i ) , dataMember ) ;
196+ }
197+
198+ public static IReadOnlySet < TNumber > ToNumberIReadOnlySet < TNumber > ( List < string > ns , string ? dataMember )
199+ where TNumber : struct , INumber < TNumber >
200+ {
201+ return ToNumberSet < TNumber , HashSet < TNumber > > ( ns , i => new HashSet < TNumber > ( i ) , dataMember ) ;
202+ }
203+
204+ public static HashSet < TNumber > ToNumberHashSet < TNumber > ( List < string > ns , string ? dataMember )
205+ where TNumber : struct , INumber < TNumber >
206+ {
207+ return ToNumberSet < TNumber , HashSet < TNumber > > ( ns , i => new HashSet < TNumber > ( i ) , dataMember ) ;
208+ }
209+
210+ public static SortedSet < TNumber > ToNumberSortedSet < TNumber > ( List < string > ns , string ? dataMember )
211+ where TNumber : struct , INumber < TNumber >
212+ {
213+ var span = AsSpan ( ns ) ;
214+ var set = new SortedSet < TNumber > ( ) ;
215+ foreach ( var se in span )
216+ {
217+ if ( se is null )
218+ throw ExceptionHelper . NotNull ( $ "{ dataMember } [UNKNOWN]") ;
219+
220+ set . Add ( TNumber . Parse ( se , null ) ) ;
221+ }
222+
223+ return set ;
224+ }
225+
226+ public static ISet < TNumber ? > ToNullableNumberISet < TNumber > ( List < string ? > ns , string ? dataMember )
227+ where TNumber : struct , INumber < TNumber >
228+ {
229+ return ToNullableNumberSet < TNumber , HashSet < TNumber ? > > ( ns , i => new HashSet < TNumber ? > ( i ) , dataMember ) ;
230+ }
231+
232+ public static IReadOnlySet < TNumber ? > ToNullableNumberIReadOnlySet < TNumber > ( List < string ? > ns , string ? dataMember )
233+ where TNumber : struct , INumber < TNumber >
234+ {
235+ return ToNullableNumberSet < TNumber , HashSet < TNumber ? > > ( ns , i => new HashSet < TNumber ? > ( i ) , dataMember ) ;
236+ }
237+
238+ public static HashSet < TNumber ? > ToNullableNumberHashSet < TNumber > ( List < string ? > ns , string ? dataMember )
239+ where TNumber : struct , INumber < TNumber >
240+ {
241+ return ToNullableNumberSet < TNumber , HashSet < TNumber ? > > ( ns , i => new HashSet < TNumber ? > ( i ) , dataMember ) ;
242+ }
243+
244+ public static SortedSet < TNumber ? > ToNullableNumberSortedSet < TNumber > ( List < string ? > ns , string ? _ )
245+ where TNumber : struct , INumber < TNumber >
246+ {
247+ return new SortedSet < TNumber ? > ( ns . Select ( x => x is null ? ( TNumber ? ) null : TNumber . Parse ( x , null ) ) ) ;
248+ }
48249
49250 public static ILookup < string , T > ToLookup < T , TArgument > (
50251 Dictionary < string , AttributeValue > dictionary ,
@@ -134,15 +335,20 @@ public static AttributeValue FromEnumerable<T, TArgument>(
134335 string ? dataMember ,
135336 Func < T , TArgument , string ? , AttributeValue > resultSelector )
136337 {
137- var attributeValues = enumerable . TryGetNonEnumeratedCount ( out var count )
138- ? new List < AttributeValue > ( count )
139- : new List < AttributeValue > ( ) ;
338+ if ( enumerable . TryGetNonEnumeratedCount ( out var count ) is false )
339+ return new AttributeValue
340+ {
341+ L = [ ..enumerable . Select ( ( element , i ) => resultSelector ( element , argument , $ "{ dataMember } [{ i } ]") ) ]
342+ } ;
140343
344+ if ( count == 0 )
345+ return new AttributeValue { L = [ ] } ;
346+
347+ var list = new List < AttributeValue > ( count ) ;
141348 foreach ( var ( element , i ) in enumerable . Select ( ( x , y ) => ( x , y ) ) )
142- attributeValues . Add ( resultSelector ( element , argument , $ "{ dataMember } [{ i } ]") ) ;
349+ list . Add ( resultSelector ( element , argument , $ "{ dataMember } [{ i } ]") ) ;
143350
144-
145- return new AttributeValue { L = attributeValues } ;
351+ return new AttributeValue { L = list } ;
146352 }
147353
148354 public static List < TResult > ToList < TResult , TArgument > (
0 commit comments