@@ -4,7 +4,7 @@ use alloc::boxed::Box;
44use alloc:: string:: String ;
55use core:: { ffi:: CStr , ptr} ;
66
7- use crate :: { module:: Declared , qjs, Ctx , Module , Object , Result , Value } ;
7+ use crate :: { module:: Declared , object :: ObjectKeysIter , qjs, Ctx , Module , Object , Result , Value } ;
88
99mod builtin_loader;
1010mod builtin_resolver;
@@ -84,6 +84,11 @@ impl<'js> ImportAttributes<'js> {
8484 pub fn get_type ( & self ) -> Result < Option < String > > {
8585 self . get ( "type" )
8686 }
87+
88+ /// Get an iterator over the attribute keys
89+ pub fn keys ( & self ) -> ObjectKeysIter < ' js , String > {
90+ self . 0 . keys ( )
91+ }
8792}
8893
8994/// Module loader interface
@@ -574,4 +579,59 @@ mod test {
574579 . expect ( "missing type attribute" ) ;
575580 } ) ;
576581 }
582+
583+ struct KeysCapturingLoader {
584+ captured_keys : Arc < Mutex < Vec < String > > > ,
585+ }
586+
587+ impl Loader for KeysCapturingLoader {
588+ fn load < ' js > (
589+ & mut self ,
590+ ctx : & Ctx < ' js > ,
591+ name : & str ,
592+ attributes : Option < super :: ImportAttributes < ' js > > ,
593+ ) -> Result < Module < ' js > > {
594+ if let Some ( attrs) = & attributes {
595+ let keys: Vec < String > = attrs. keys ( ) . collect :: < Result < Vec < _ > > > ( ) . unwrap ( ) ;
596+ * self . captured_keys . lock ( ) . unwrap ( ) = keys;
597+ }
598+
599+ if name == "data" {
600+ Module :: declare ( ctx. clone ( ) , name, "export default { value: 42 };" )
601+ } else {
602+ Err ( Error :: new_loading_message ( name, "module not found" ) )
603+ }
604+ }
605+ }
606+
607+ #[ test]
608+ fn import_attributes_keys ( ) {
609+ let captured_keys = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
610+ let loader = KeysCapturingLoader {
611+ captured_keys : captured_keys. clone ( ) ,
612+ } ;
613+
614+ let rt = Runtime :: new ( ) . unwrap ( ) ;
615+ let ctx = Context :: full ( & rt) . unwrap ( ) ;
616+ rt. set_loader ( IdentityResolver , loader) ;
617+
618+ ctx. with ( |ctx| {
619+ Module :: evaluate (
620+ ctx,
621+ "test" ,
622+ r#"
623+ import data from "data" with { type: "json", encoding: "utf-8" };
624+ export default data;
625+ "# ,
626+ )
627+ . unwrap ( )
628+ . finish :: < ( ) > ( )
629+ . unwrap ( ) ;
630+ } ) ;
631+
632+ let keys = captured_keys. lock ( ) . unwrap ( ) ;
633+ assert_eq ! ( keys. len( ) , 2 ) ;
634+ assert ! ( keys. contains( & "type" . to_string( ) ) ) ;
635+ assert ! ( keys. contains( & "encoding" . to_string( ) ) ) ;
636+ }
577637}
0 commit comments