cli.rs (4006B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use repl_ng::Parameter; 6 7 use std::fs::File; 8 use std::io::BufWriter; 9 10 use crate::net; 11 use crate::command; 12 13 // Command line interface for the WR debugger 14 15 struct Context { 16 net: net::HttpConnection, 17 cmd_list: command::CommandList, 18 } 19 20 impl repl_ng::Prompt for Context { 21 fn prompt(&self) -> String { 22 "> ".to_string() 23 } 24 25 fn complete(&self, _command: &str, _args: &[&str], _incomplete: &str) -> Vec<String> { 26 // TODO: Add auto completion of command params 27 vec![] 28 } 29 } 30 31 pub struct Cli { 32 repl: repl_ng::Repl<Context, repl_ng::Error>, 33 } 34 35 impl Cli { 36 pub fn new( 37 host: &str, 38 cmd_list: command::CommandList, 39 ) -> Self { 40 let mut cmds = Vec::new(); 41 for cmd in cmd_list.cmds() { 42 let desc = cmd.descriptor(); 43 44 let mut repl_cmd = repl_ng::Command::new( 45 desc.name, 46 |args, ctx: &mut Context| { 47 let cmd = ctx.cmd_list.get_mut(desc.name).unwrap(); 48 let mut ctx = command::CommandContext::new( 49 args, 50 &mut ctx.net, 51 ); 52 let result = cmd.run(&mut ctx); 53 match result { 54 command::CommandOutput::Log(msg) => { 55 Ok(Some(msg)) 56 } 57 command::CommandOutput::Err(msg) => { 58 Ok(Some(msg)) 59 } 60 command::CommandOutput::TextDocument { content, .. } => { 61 Ok(Some(content)) 62 } 63 command::CommandOutput::SerdeDocument { content, .. } => { 64 Ok(Some(content)) 65 } 66 command::CommandOutput::Textures(textures) => { 67 for texture in textures { 68 let name = format!("{}.png", texture.name); 69 println!("saving {name:?}"); 70 71 let file = File::create(name).unwrap(); 72 let ref mut w = BufWriter::new(file); 73 74 let mut encoder = png::Encoder::new(w, texture.width, texture.height); 75 encoder.set_color(png::ColorType::RGBA); 76 encoder.set_depth(png::BitDepth::Eight); 77 let mut writer = encoder.write_header().unwrap(); 78 79 writer.write_image_data(&texture.data).unwrap(); // Save 80 } 81 Ok(None) 82 } 83 } 84 }, 85 ).with_help(desc.help); 86 87 if let Some(alias) = desc.alias { 88 repl_cmd = repl_cmd.with_alias(alias); 89 } 90 91 for param_desc in desc.params { 92 let mut param = Parameter::new(param_desc.name); 93 94 if param_desc.is_required { 95 param = param.set_required(true).unwrap(); 96 } 97 98 repl_cmd = repl_cmd.with_parameter(param).expect("invalid param"); 99 } 100 101 cmds.push(repl_cmd); 102 } 103 104 let ctx = Context { 105 net: net::HttpConnection::new(host), 106 cmd_list, 107 }; 108 109 let mut repl = repl_ng::Repl::new(ctx) 110 .with_name("WebRender Debug Shell [Ctrl-D to quit, help for help]") 111 .with_version("v0.1.0") 112 .use_completion(true); 113 114 for cmd in cmds { 115 repl = repl.add_command(cmd); 116 } 117 118 Cli { 119 repl, 120 } 121 } 122 123 pub fn run(mut self) { 124 self.repl.run().ok(); 125 } 126 }