@@ -183,3 +183,108 @@ impl_code_type_for_compound!(SequenceCodeType, "List<{}>", "Sequence{}");
183183
184184impl_renderable_for_compound ! ( OptionalCodeType , "{}?" , "FfiConverterOptional{}" ) ;
185185impl_renderable_for_compound ! ( SequenceCodeType , "FfiConverterSequence{}" ) ;
186+
187+ // Map<K, V>
188+ #[ derive( Debug ) ]
189+ pub struct MapCodeType {
190+ self_type : Type ,
191+ key : Type ,
192+ value : Type ,
193+ }
194+
195+ impl MapCodeType {
196+ pub fn new ( self_type : Type , key : Type , value : Type ) -> Self {
197+ Self { self_type, key, value }
198+ }
199+
200+ fn key ( & self ) -> & Type {
201+ & self . key
202+ }
203+
204+ fn value ( & self ) -> & Type {
205+ & self . value
206+ }
207+ }
208+
209+ impl CodeType for MapCodeType {
210+ fn type_label ( & self ) -> String {
211+ format ! (
212+ "Map<{}, {}>" ,
213+ DartCodeOracle :: find( self . key( ) ) . type_label( ) ,
214+ DartCodeOracle :: find( self . value( ) ) . type_label( )
215+ )
216+ }
217+
218+ fn canonical_name ( & self ) -> String {
219+ let key = DartCodeOracle :: find ( self . key ( ) ) . canonical_name ( ) ;
220+ let val = DartCodeOracle :: find ( self . value ( ) ) . canonical_name ( ) ;
221+ format ! ( "Map{}To{}" , key, val)
222+ }
223+ }
224+
225+ impl Renderable for MapCodeType {
226+ fn render_type_helper ( & self , type_helper : & dyn TypeHelperRenderer ) -> dart:: Tokens {
227+ type_helper. include_once_check ( & self . ffi_converter_name ( ) , & self . self_type ) ;
228+
229+ let key_codetype = DartCodeOracle :: find ( self . key ( ) ) ;
230+ let val_codetype = DartCodeOracle :: find ( self . value ( ) ) ;
231+
232+ type_helper. include_once_check ( & key_codetype. canonical_name ( ) , self . key ( ) ) ;
233+ type_helper. include_once_check ( & val_codetype. canonical_name ( ) , self . value ( ) ) ;
234+
235+ let cl_name = & self . ffi_converter_name ( ) ;
236+ let key_type_label_owned = key_codetype. type_label ( ) ;
237+ let val_type_label_owned = val_codetype. type_label ( ) ;
238+ let key_type_label = & key_type_label_owned;
239+ let val_type_label = & val_type_label_owned;
240+
241+ let key_conv_owned = key_codetype. ffi_converter_name ( ) ;
242+ let val_conv_owned = val_codetype. ffi_converter_name ( ) ;
243+ let key_conv = & key_conv_owned;
244+ let val_conv = & val_conv_owned;
245+
246+ quote ! {
247+ class $cl_name {
248+ static Map <$key_type_label, $val_type_label> lift( RustBuffer buf) {
249+ return $cl_name. read( buf. asUint8List( ) ) . value;
250+ }
251+
252+ static LiftRetVal <Map <$key_type_label, $val_type_label>> read( Uint8List buf) {
253+ final map = <$key_type_label, $val_type_label>{ } ;
254+ final length = buf. buffer. asByteData( buf. offsetInBytes) . getInt32( 0 ) ;
255+ int offset = buf. offsetInBytes + 4 ;
256+ for ( var i = 0 ; i < length; i++) {
257+ final k = $key_conv. read( Uint8List . view( buf. buffer, offset) ) ;
258+ offset += k. bytesRead;
259+ final v = $val_conv. read( Uint8List . view( buf. buffer, offset) ) ;
260+ offset += v. bytesRead;
261+ map[ k. value] = v. value;
262+ }
263+ return LiftRetVal ( map, offset - buf. offsetInBytes) ;
264+ }
265+
266+ static int write( Map <$key_type_label, $val_type_label> value, Uint8List buf) {
267+ buf. buffer. asByteData( buf. offsetInBytes) . setInt32( 0 , value. length) ;
268+ int offset = buf. offsetInBytes + 4 ;
269+ for ( final entry in value. entries) {
270+ offset += $key_conv. write( entry. key, Uint8List . view( buf. buffer, offset) ) ;
271+ offset += $val_conv. write( entry. value, Uint8List . view( buf. buffer, offset) ) ;
272+ }
273+ return offset - buf. offsetInBytes;
274+ }
275+
276+ static int allocationSize( Map <$key_type_label, $val_type_label> value) {
277+ return value. entries
278+ . map( ( e) => $key_conv. allocationSize( e. key) + $val_conv. allocationSize( e. value) )
279+ . fold( 4 , ( a, b) => a + b) ;
280+ }
281+
282+ static RustBuffer lower( Map <$key_type_label, $val_type_label> value) {
283+ final buf = Uint8List ( allocationSize( value) ) ;
284+ write( value, buf) ;
285+ return toRustBuffer( buf) ;
286+ }
287+ }
288+ }
289+ }
290+ }
0 commit comments