1
+ use crate :: api:: config:: PluginConfig ;
1
2
use crate :: async_runtime:: Mutex ;
2
-
3
3
use crate :: ApplicationDispatcherExt ;
4
4
5
+ use futures:: future:: join_all;
6
+
5
7
use std:: sync:: Arc ;
6
8
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
+
7
30
/// The plugin interface.
8
31
#[ async_trait:: async_trait]
9
32
pub 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
+
10
42
/// The JS script to evaluate on init.
11
43
async fn init_script ( & self ) -> Option < String > {
12
44
None
13
45
}
46
+
14
47
/// Callback invoked when the webview is created.
15
48
#[ allow( unused_variables) ]
16
49
async fn created ( & self , dispatcher : D ) { }
@@ -21,8 +54,8 @@ pub trait Plugin<D: ApplicationDispatcherExt + 'static>: Sync {
21
54
22
55
/// Add invoke_handler API extension commands.
23
56
#[ 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 )
26
59
}
27
60
}
28
61
@@ -38,18 +71,39 @@ pub async fn register<D: ApplicationDispatcherExt + 'static>(
38
71
plugins. push ( Box :: new ( plugin) ) ;
39
72
}
40
73
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
+
41
92
pub ( crate ) async fn init_script < D : ApplicationDispatcherExt + ' static > (
42
93
store : & PluginStore < D > ,
43
94
) -> String {
44
- let mut init = String :: new ( ) ;
45
-
46
95
let plugins = store. lock ( ) . await ;
96
+ let mut futures = Vec :: new ( ) ;
47
97
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 {
49
104
init. push_str ( & format ! ( "(function () {{ {} }})();" , init_script) ) ;
50
105
}
51
106
}
52
-
53
107
init
54
108
}
55
109
@@ -58,39 +112,40 @@ pub(crate) async fn created<D: ApplicationDispatcherExt + 'static>(
58
112
dispatcher : & mut D ,
59
113
) {
60
114
let plugins = store. lock ( ) . await ;
115
+ let mut futures = Vec :: new ( ) ;
61
116
for plugin in plugins. iter ( ) {
62
- plugin. created ( dispatcher. clone ( ) ) . await ;
117
+ futures . push ( plugin. created ( dispatcher. clone ( ) ) ) ;
63
118
}
119
+ join_all ( futures) . await ;
64
120
}
65
121
66
122
pub ( crate ) async fn ready < D : ApplicationDispatcherExt + ' static > (
67
123
store : & PluginStore < D > ,
68
124
dispatcher : & mut D ,
69
125
) {
70
126
let plugins = store. lock ( ) . await ;
127
+ let mut futures = Vec :: new ( ) ;
71
128
for plugin in plugins. iter ( ) {
72
- plugin. ready ( dispatcher. clone ( ) ) . await ;
129
+ futures . push ( plugin. ready ( dispatcher. clone ( ) ) ) ;
73
130
}
131
+ join_all ( futures) . await ;
74
132
}
75
133
76
134
pub ( crate ) async fn extend_api < D : ApplicationDispatcherExt + ' static > (
77
135
store : & PluginStore < D > ,
78
136
dispatcher : & mut D ,
79
137
arg : & str ,
80
- ) -> Result < bool , String > {
138
+ ) -> Result < bool , Error > {
81
139
let plugins = store. lock ( ) . await ;
82
140
for ext in plugins. iter ( ) {
83
141
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 ) ;
93
144
}
145
+ Err ( e) => match e {
146
+ Error :: UnknownApi => { }
147
+ _ => return Err ( e) ,
148
+ } ,
94
149
}
95
150
}
96
151
Ok ( false )
0 commit comments