1+ use crate :: api:: config:: PluginConfig ;
12use crate :: async_runtime:: Mutex ;
2-
33use crate :: ApplicationDispatcherExt ;
44
5+ use futures:: future:: join_all;
6+
57use std:: sync:: Arc ;
68
9+ /// The plugin error type.
10+ #[ derive( Debug , thiserror:: Error ) ]
11+ pub enum Error {
12+ /// Failed to serialize/deserialize.
13+ #[ error( "JSON error: {0}" ) ]
14+ Json ( serde_json:: Error ) ,
15+ /// Unknown API type.
16+ #[ error( "unknown API" ) ]
17+ UnknownApi ,
18+ }
19+
20+ impl From < serde_json:: Error > for Error {
21+ fn from ( error : serde_json:: Error ) -> Self {
22+ if error. to_string ( ) . contains ( "unknown variant" ) {
23+ Self :: UnknownApi
24+ } else {
25+ Self :: Json ( error)
26+ }
27+ }
28+ }
29+
730/// The plugin interface.
831#[ async_trait:: async_trait]
932pub trait Plugin < D : ApplicationDispatcherExt + ' static > : Sync {
33+ /// The plugin name. Used as key on the plugin config object.
34+ fn name ( & self ) -> & ' static str ;
35+
36+ /// Initialize the plugin.
37+ #[ allow( unused_variables) ]
38+ async fn initialize ( & self , config : String ) -> Result < ( ) , Error > {
39+ Ok ( ( ) )
40+ }
41+
1042 /// The JS script to evaluate on init.
1143 async fn init_script ( & self ) -> Option < String > {
1244 None
1345 }
46+
1447 /// Callback invoked when the webview is created.
1548 #[ allow( unused_variables) ]
1649 async fn created ( & self , dispatcher : D ) { }
@@ -21,8 +54,8 @@ pub trait Plugin<D: ApplicationDispatcherExt + 'static>: Sync {
2154
2255 /// Add invoke_handler API extension commands.
2356 #[ allow( unused_variables) ]
24- async fn extend_api ( & self , dispatcher : D , payload : & str ) -> Result < bool , String > {
25- Err ( "unknown variant" . to_string ( ) )
57+ async fn extend_api ( & self , dispatcher : D , payload : & str ) -> Result < ( ) , Error > {
58+ Err ( Error :: UnknownApi )
2659 }
2760}
2861
@@ -38,18 +71,39 @@ pub async fn register<D: ApplicationDispatcherExt + 'static>(
3871 plugins. push ( Box :: new ( plugin) ) ;
3972}
4073
74+ pub ( crate ) async fn initialize < D : ApplicationDispatcherExt + ' static > (
75+ store : & PluginStore < D > ,
76+ plugins_config : PluginConfig ,
77+ ) -> crate :: Result < ( ) > {
78+ let plugins = store. lock ( ) . await ;
79+ let mut futures = Vec :: new ( ) ;
80+ for plugin in plugins. iter ( ) {
81+ let plugin_config = plugins_config. get ( plugin. name ( ) ) ;
82+ futures. push ( plugin. initialize ( plugin_config) ) ;
83+ }
84+
85+ for res in join_all ( futures) . await {
86+ res?;
87+ }
88+
89+ Ok ( ( ) )
90+ }
91+
4192pub ( crate ) async fn init_script < D : ApplicationDispatcherExt + ' static > (
4293 store : & PluginStore < D > ,
4394) -> String {
44- let mut init = String :: new ( ) ;
45-
4695 let plugins = store. lock ( ) . await ;
96+ let mut futures = Vec :: new ( ) ;
4797 for plugin in plugins. iter ( ) {
48- if let Some ( init_script) = plugin. init_script ( ) . await {
98+ futures. push ( plugin. init_script ( ) ) ;
99+ }
100+
101+ let mut init = String :: new ( ) ;
102+ for res in join_all ( futures) . await {
103+ if let Some ( init_script) = res {
49104 init. push_str ( & format ! ( "(function () {{ {} }})();" , init_script) ) ;
50105 }
51106 }
52-
53107 init
54108}
55109
@@ -58,39 +112,40 @@ pub(crate) async fn created<D: ApplicationDispatcherExt + 'static>(
58112 dispatcher : & mut D ,
59113) {
60114 let plugins = store. lock ( ) . await ;
115+ let mut futures = Vec :: new ( ) ;
61116 for plugin in plugins. iter ( ) {
62- plugin. created ( dispatcher. clone ( ) ) . await ;
117+ futures . push ( plugin. created ( dispatcher. clone ( ) ) ) ;
63118 }
119+ join_all ( futures) . await ;
64120}
65121
66122pub ( crate ) async fn ready < D : ApplicationDispatcherExt + ' static > (
67123 store : & PluginStore < D > ,
68124 dispatcher : & mut D ,
69125) {
70126 let plugins = store. lock ( ) . await ;
127+ let mut futures = Vec :: new ( ) ;
71128 for plugin in plugins. iter ( ) {
72- plugin. ready ( dispatcher. clone ( ) ) . await ;
129+ futures . push ( plugin. ready ( dispatcher. clone ( ) ) ) ;
73130 }
131+ join_all ( futures) . await ;
74132}
75133
76134pub ( crate ) async fn extend_api < D : ApplicationDispatcherExt + ' static > (
77135 store : & PluginStore < D > ,
78136 dispatcher : & mut D ,
79137 arg : & str ,
80- ) -> Result < bool , String > {
138+ ) -> Result < bool , Error > {
81139 let plugins = store. lock ( ) . await ;
82140 for ext in plugins. iter ( ) {
83141 match ext. extend_api ( dispatcher. clone ( ) , arg) . await {
84- Ok ( handled) => {
85- if handled {
86- return Ok ( true ) ;
87- }
88- }
89- Err ( e) => {
90- if !e. contains ( "unknown variant" ) {
91- return Err ( e) ;
92- }
142+ Ok ( _) => {
143+ return Ok ( true ) ;
93144 }
145+ Err ( e) => match e {
146+ Error :: UnknownApi => { }
147+ _ => return Err ( e) ,
148+ } ,
94149 }
95150 }
96151 Ok ( false )
0 commit comments