tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }