1- use clap:: Parser ;
1+ use clap:: { Parser , Subcommand } ;
22use std:: {
33 env,
44 error:: Error ,
@@ -10,7 +10,27 @@ use wasmtime::{Engine, Linker, Module, Store};
1010use wasmtime_wasi:: WasiCtxBuilder ;
1111
1212#[ derive( Parser , Debug ) ]
13- struct JSONCodeGen {
13+ #[ command( about = "JSON code generator" ) ]
14+ struct Args {
15+ #[ arg( long, env( "JSONCODEGEN_RUNTIME" ) , default_value_os_t = default_runtime_dir( ) ) ]
16+ runtime_dir : PathBuf ,
17+
18+ #[ command( subcommand) ]
19+ command : Commands ,
20+ }
21+
22+ #[ derive( Subcommand , Debug ) ]
23+ enum Commands {
24+ /// Generate code from a JSON file
25+ Gen ( GenArgs ) ,
26+
27+ /// Update generated artifacts
28+ #[ command( subcommand) ]
29+ Update ( UpdateArgs ) ,
30+ }
31+
32+ #[ derive( Parser , Debug ) ]
33+ struct GenArgs {
1434 /// input json filepath
1535 #[ arg( short, long) ]
1636 filepath : String ,
@@ -22,64 +42,75 @@ struct JSONCodeGen {
2242 /// Optional output file; if omitted, prints to stdout
2343 #[ arg( short, long) ]
2444 output : Option < PathBuf > ,
25-
26- #[ arg( long, env( "JSONCODEGEN_RUNTIME" ) ) ]
27- runtime_dir : Option < PathBuf > ,
2845}
2946
30- fn main ( ) -> Result < ( ) , Box < dyn Error > > {
31- let args = JSONCodeGen :: parse ( ) ;
32-
33- let runtime_dir = args
34- . runtime_dir
35- . or_else ( || {
36- env:: home_dir ( ) . map ( |mut home| {
37- home. push ( ".jsoncodegen" ) ;
38- home
39- } )
40- } )
41- . ok_or ( "default runtime directory unavailable. please specify an alternate manually." ) ?;
42-
43- let codegen_wasm_path =
44- runtime_dir. join ( format ! ( "jsoncodegen-{}-wasm32-wasip1.wasm" , args. lang) ) ;
45-
46- // Check if WASM binary exists locally, if not download it
47- if !codegen_wasm_path. is_file ( ) {
48- eprintln ! ( "WASM binary not found locally" ) ;
49- fetch_latest_wasm_release ( & args. lang , & codegen_wasm_path) ?;
50- }
51-
52- let ctx = {
53- let mut builder = WasiCtxBuilder :: new ( ) ;
47+ #[ derive( Subcommand , Debug ) ]
48+ enum UpdateArgs {
49+ /// Update a specific language
50+ Lang {
51+ /// Language to update
52+ lang : String ,
53+ } ,
5454
55- builder
56- . stdin ( {
57- let file = File :: open ( args. filepath ) ?;
58- wasmtime_wasi:: cli:: InputFile :: new ( file)
59- } )
60- . stderr ( wasmtime_wasi:: cli:: stderr ( ) ) ;
55+ /// Update all languages
56+ All ,
57+ }
6158
62- match args. output {
63- Some ( out_path) => {
64- let file = File :: create ( out_path) ?;
65- builder. stdout ( wasmtime_wasi:: cli:: OutputFile :: new ( file) )
59+ fn main ( ) -> Result < ( ) , Box < dyn Error > > {
60+ let Args {
61+ runtime_dir,
62+ command,
63+ } = Args :: parse ( ) ;
64+
65+ match command {
66+ Commands :: Gen ( gen_args) => {
67+ let codegen_wasm_path = runtime_dir. join ( lang_2_wasm_filename ( & gen_args. lang ) ) ;
68+
69+ // Check if WASM binary exists locally, if not download it
70+ if !codegen_wasm_path. is_file ( ) {
71+ eprintln ! ( "WASM binary not found locally" ) ;
72+ fetch_latest_wasm_release ( & gen_args. lang , & codegen_wasm_path) ?;
6673 }
67- None => builder. stdout ( wasmtime_wasi:: cli:: stdout ( ) ) ,
68- } ;
69-
70- builder. build_p1 ( )
71- } ;
7274
73- let engine = Engine :: default ( ) ;
74- let mut linker = Linker :: < wasmtime_wasi:: p1:: WasiP1Ctx > :: new ( & engine) ;
75- wasmtime_wasi:: p1:: add_to_linker_sync ( & mut linker, |s| s) ?;
76-
77- let module = Module :: from_file ( & engine, codegen_wasm_path) ?;
78- let mut store = Store :: new ( & engine, ctx) ;
79- let instance = linker. instantiate ( & mut store, & module) ?;
80-
81- let start = instance. get_typed_func :: < ( ) , ( ) > ( & mut store, "_start" ) ?;
82- start. call ( & mut store, ( ) ) ?;
75+ let ctx = {
76+ let mut builder = WasiCtxBuilder :: new ( ) ;
77+
78+ builder
79+ . stdin ( {
80+ let file = File :: open ( gen_args. filepath ) ?;
81+ wasmtime_wasi:: cli:: InputFile :: new ( file)
82+ } )
83+ . stderr ( wasmtime_wasi:: cli:: stderr ( ) ) ;
84+
85+ match gen_args. output {
86+ Some ( out_path) => {
87+ let file = File :: create ( out_path) ?;
88+ builder. stdout ( wasmtime_wasi:: cli:: OutputFile :: new ( file) )
89+ }
90+ None => builder. stdout ( wasmtime_wasi:: cli:: stdout ( ) ) ,
91+ } ;
92+
93+ builder. build_p1 ( )
94+ } ;
95+
96+ let engine = Engine :: default ( ) ;
97+ let mut linker = Linker :: < wasmtime_wasi:: p1:: WasiP1Ctx > :: new ( & engine) ;
98+ wasmtime_wasi:: p1:: add_to_linker_sync ( & mut linker, |s| s) ?;
99+
100+ let module = Module :: from_file ( & engine, codegen_wasm_path) ?;
101+ let mut store = Store :: new ( & engine, ctx) ;
102+ let instance = linker. instantiate ( & mut store, & module) ?;
103+
104+ let start = instance. get_typed_func :: < ( ) , ( ) > ( & mut store, "_start" ) ?;
105+ start. call ( & mut store, ( ) ) ?;
106+ }
107+ Commands :: Update ( update_args) => match update_args {
108+ UpdateArgs :: Lang { lang } => {
109+ fetch_latest_wasm_release ( & lang, & runtime_dir. join ( lang_2_wasm_filename ( & lang) ) ) ?
110+ }
111+ UpdateArgs :: All => unimplemented ! ( ) ,
112+ } ,
113+ }
83114
84115 Ok ( ( ) )
85116}
@@ -91,10 +122,7 @@ fn fetch_latest_wasm_release(lang: &str, dest_path: &PathBuf) -> Result<(), Box<
91122 . user_agent ( "jsoncodegen" )
92123 . build ( ) ?;
93124
94- let url = format ! (
95- "https://zahash.github.io/jsoncodegen-{}-wasm32-wasip1.wasm" ,
96- lang
97- ) ;
125+ let url = format ! ( "https://zahash.github.io/{}" , lang_2_wasm_filename( lang) ) ;
98126
99127 let response = client. get ( & url) . send ( ) ?;
100128 if !response. status ( ) . is_success ( ) {
@@ -112,3 +140,15 @@ fn fetch_latest_wasm_release(lang: &str, dest_path: &PathBuf) -> Result<(), Box<
112140 eprintln ! ( "Successfully downloaded to: {}" , dest_path. display( ) ) ;
113141 Ok ( ( ) )
114142}
143+
144+ fn default_runtime_dir ( ) -> PathBuf {
145+ let mut runtime_dir = env:: home_dir ( )
146+ . or_else ( || env:: current_dir ( ) . ok ( ) )
147+ . unwrap_or_default ( ) ;
148+ runtime_dir. push ( ".jsoncodegen" ) ;
149+ runtime_dir
150+ }
151+
152+ fn lang_2_wasm_filename ( lang : & str ) -> String {
153+ format ! ( "jsoncodegen-{}-wasm32-wasip1.wasm" , lang)
154+ }
0 commit comments