@@ -5,19 +5,99 @@ mod config;
55mod emit_rust;
66mod identifiers;
77mod parser_util;
8- mod run;
98
109fn main ( ) {
1110 entry:: main ( ) ;
1211}
1312
13+ use std:: error:: Error ;
14+ use std:: fs:: File ;
15+ use std:: io:: { self , Read } ;
16+ use std:: path:: Path ;
17+
18+ use crate :: config:: Config ;
19+ use crate :: parser_util:: JavaClass ;
20+
21+ /// The core function of this library: Generate Rust code to access Java APIs.
22+ pub fn run ( config : impl Into < Config > ) -> Result < ( ) , Box < dyn Error > > {
23+ let config: Config = config. into ( ) ;
24+ println ! ( "output: {}" , config. output. display( ) ) ;
25+
26+ let mut context = emit_rust:: Context :: new ( & config) ;
27+ for file in config. input . iter ( ) {
28+ gather_file ( & mut context, file) ?;
29+ }
30+
31+ let mut out = Vec :: with_capacity ( 4096 ) ;
32+ context. write ( & mut out) ?;
33+ util:: write_generated ( & context, & config. output , & out[ ..] ) ?;
34+
35+ Ok ( ( ) )
36+ }
37+
38+ fn gather_file ( context : & mut emit_rust:: Context , path : & Path ) -> Result < ( ) , Box < dyn Error > > {
39+ let verbose = context. config . logging_verbose ;
40+
41+ context
42+ . progress
43+ . lock ( )
44+ . unwrap ( )
45+ . update ( format ! ( "reading {}..." , path. display( ) ) . as_str ( ) ) ;
46+
47+ let ext = if let Some ( ext) = path. extension ( ) {
48+ ext
49+ } else {
50+ return Err ( io:: Error :: new (
51+ io:: ErrorKind :: InvalidInput ,
52+ "Input files must have an extension" ,
53+ ) ) ?;
54+ } ;
55+
56+ match ext. to_string_lossy ( ) . to_ascii_lowercase ( ) . as_str ( ) {
57+ "class" => {
58+ let class = JavaClass :: read ( std:: fs:: read ( path) ?) ?;
59+ context. add_class ( class) ?;
60+ }
61+ "jar" => {
62+ let mut jar = zip:: ZipArchive :: new ( io:: BufReader :: new ( File :: open ( path) ?) ) ?;
63+ let n = jar. len ( ) ;
64+
65+ for i in 0 ..n {
66+ let mut file = jar. by_index ( i) ?;
67+ if !file. name ( ) . ends_with ( ".class" ) {
68+ continue ;
69+ }
70+
71+ if verbose {
72+ context
73+ . progress
74+ . lock ( )
75+ . unwrap ( )
76+ . update ( format ! ( " reading {:3}/{}: {}..." , i, n, file. name( ) ) . as_str ( ) ) ;
77+ }
78+
79+ let mut buf = Vec :: new ( ) ;
80+ file. read_to_end ( & mut buf) ?;
81+ let class = JavaClass :: read ( buf) ?;
82+ context. add_class ( class) ?;
83+ }
84+ }
85+ unknown => {
86+ Err ( io:: Error :: new (
87+ io:: ErrorKind :: InvalidInput ,
88+ format ! ( "Input files must have a '.class' or '.jar' extension, not a '.{unknown}' extension" , ) ,
89+ ) ) ?;
90+ }
91+ }
92+ Ok ( ( ) )
93+ }
94+
1495mod entry {
1596 use std:: path:: PathBuf ;
1697
1798 use clap:: { Parser , Subcommand } ;
1899
19- use crate :: config;
20- use crate :: run:: run;
100+ use crate :: { config, run} ;
21101
22102 /// Autogenerate glue code for access Android JVM APIs from Rust
23103 #[ derive( Parser , Debug ) ]
0 commit comments