44
55use proc_macro2:: { Ident , Span , TokenStream } ;
66use quote:: { quote, ToTokens } ;
7- use std:: { env :: VarError , path:: PathBuf } ;
7+ use std:: path:: PathBuf ;
88use syn:: {
99 parse:: { Parse , ParseBuffer } ,
1010 punctuated:: Punctuated ,
11- LitStr , PathArguments , PathSegment , Token ,
11+ Expr , ExprLit , Lit , LitStr , Meta , PathArguments , PathSegment , Token ,
1212} ;
1313use tauri_codegen:: { context_codegen, get_config, ContextData } ;
1414use tauri_utils:: { config:: parse:: does_supported_file_name_exist, platform:: Target } ;
1515
1616pub ( crate ) struct ContextItems {
1717 config_file : PathBuf ,
1818 root : syn:: Path ,
19+ capabilities : Option < Vec < PathBuf > > ,
1920}
2021
2122impl Parse for ContextItems {
@@ -26,51 +27,92 @@ impl Parse for ContextItems {
2627 . map ( Target :: from_triple)
2728 . unwrap_or_else ( |_| Target :: current ( ) ) ;
2829
29- let config_file = if input . is_empty ( ) {
30- std :: env :: var ( "CARGO_MANIFEST_DIR" ) . map ( |m| PathBuf :: from ( m ) . join ( "tauri.conf.json" ) )
31- } else {
32- let raw : LitStr = input. parse ( ) ? ;
30+ let mut root = None ;
31+ let mut capabilities = None ;
32+ let config_file = input . parse :: < LitStr > ( ) . ok ( ) . map ( |raw| {
33+ let _ = input. parse :: < Token ! [ , ] > ( ) ;
3334 let path = PathBuf :: from ( raw. value ( ) ) ;
3435 if path. is_relative ( ) {
35- std:: env:: var ( "CARGO_MANIFEST_DIR" ) . map ( |m| PathBuf :: from ( m) . join ( path) )
36+ std:: env:: var ( "CARGO_MANIFEST_DIR" )
37+ . map ( |m| PathBuf :: from ( m) . join ( path) )
38+ . map_err ( |e| e. to_string ( ) )
3639 } else {
3740 Ok ( path)
3841 }
39- }
40- . map_err ( |error| match error {
41- VarError :: NotPresent => "no CARGO_MANIFEST_DIR env var, this should be set by cargo" . into ( ) ,
42- VarError :: NotUnicode ( _) => "CARGO_MANIFEST_DIR env var contained invalid utf8" . into ( ) ,
43- } )
44- . and_then ( |path| {
45- if does_supported_file_name_exist ( target, & path) {
46- Ok ( path)
47- } else {
48- Err ( format ! (
49- "no file at path {} exists, expected tauri config file" ,
50- path. display( )
51- ) )
52- }
53- } )
54- . map_err ( |e| input. error ( e) ) ?;
42+ . and_then ( |path| {
43+ if does_supported_file_name_exist ( target, & path) {
44+ Ok ( path)
45+ } else {
46+ Err ( format ! (
47+ "no file at path {} exists, expected tauri config file" ,
48+ path. display( )
49+ ) )
50+ }
51+ } )
52+ } ) ;
5553
56- let context_path = if input. is_empty ( ) {
57- let mut segments = Punctuated :: new ( ) ;
58- segments. push ( PathSegment {
59- ident : Ident :: new ( "tauri" , Span :: call_site ( ) ) ,
60- arguments : PathArguments :: None ,
61- } ) ;
62- syn:: Path {
63- leading_colon : Some ( Token ! [ :: ] ( Span :: call_site ( ) ) ) ,
64- segments,
54+ while let Ok ( meta) = input. parse :: < Meta > ( ) {
55+ match meta {
56+ Meta :: Path ( p) => {
57+ root. replace ( p) ;
58+ }
59+ Meta :: NameValue ( v) => {
60+ if * v. path . require_ident ( ) ? == "capabilities" {
61+ if let Expr :: Array ( array) = v. value {
62+ capabilities. replace (
63+ array
64+ . elems
65+ . into_iter ( )
66+ . map ( |e| {
67+ if let Expr :: Lit ( ExprLit {
68+ attrs : _,
69+ lit : Lit :: Str ( s) ,
70+ } ) = e
71+ {
72+ Ok ( s. value ( ) . into ( ) )
73+ } else {
74+ Err ( syn:: Error :: new (
75+ input. span ( ) ,
76+ "unexpected expression for capability" ,
77+ ) )
78+ }
79+ } )
80+ . collect :: < Result < Vec < _ > , syn:: Error > > ( ) ?,
81+ ) ;
82+ } else {
83+ return Err ( syn:: Error :: new (
84+ input. span ( ) ,
85+ "unexpected value for capabilities" ,
86+ ) ) ;
87+ }
88+ }
89+ }
90+ Meta :: List ( _) => {
91+ return Err ( syn:: Error :: new ( input. span ( ) , "unexpected list input" ) ) ;
92+ }
6593 }
66- } else {
67- let _: Token ! [ , ] = input. parse ( ) ?;
68- input. call ( syn:: Path :: parse_mod_style) ?
69- } ;
94+ }
7095
7196 Ok ( Self {
72- config_file,
73- root : context_path,
97+ config_file : config_file
98+ . unwrap_or_else ( || {
99+ std:: env:: var ( "CARGO_MANIFEST_DIR" )
100+ . map ( |m| PathBuf :: from ( m) . join ( "tauri.conf.json" ) )
101+ . map_err ( |e| e. to_string ( ) )
102+ } )
103+ . map_err ( |e| input. error ( e) ) ?,
104+ root : root. unwrap_or_else ( || {
105+ let mut segments = Punctuated :: new ( ) ;
106+ segments. push ( PathSegment {
107+ ident : Ident :: new ( "tauri" , Span :: call_site ( ) ) ,
108+ arguments : PathArguments :: None ,
109+ } ) ;
110+ syn:: Path {
111+ leading_colon : Some ( Token ! [ :: ] ( Span :: call_site ( ) ) ) ,
112+ segments,
113+ }
114+ } ) ,
115+ capabilities,
74116 } )
75117 }
76118}
@@ -83,6 +125,7 @@ pub(crate) fn generate_context(context: ContextItems) -> TokenStream {
83125 config,
84126 config_parent,
85127 root : context. root . to_token_stream ( ) ,
128+ capabilities : context. capabilities ,
86129 } )
87130 . and_then ( |data| context_codegen ( data) . map_err ( |e| e. to_string ( ) ) ) ;
88131
0 commit comments