twiggy_traits/
traits.rs

1//! Common traits and types used throughout all of `twiggy`.
2#![deny(missing_docs)]
3#![deny(missing_debug_implementations)]
4
5use anyhow::anyhow;
6use std::io;
7use std::str::FromStr;
8use twiggy_ir as ir;
9
10/// An analysis takes our IR and returns some kind of data results that can be
11/// emitted.
12pub trait Analyze {
13    /// The resulting data from this analysis.
14    type Data: Emit;
15
16    /// Run this analysis on the given IR items.
17    fn analyze(items: &mut ir::Items) -> anyhow::Result<Self::Data>;
18}
19
20/// Selects the parse mode for the input data.
21#[derive(Clone, Copy, Debug)]
22pub enum ParseMode {
23    /// WebAssembly file parse mode.
24    Wasm,
25    /// DWARF sections parse mode.
26    #[cfg(feature = "dwarf")]
27    Dwarf,
28    /// Automatically determined mode of parsing, e.g. based on file extension.
29    Auto,
30}
31
32impl Default for ParseMode {
33    fn default() -> ParseMode {
34        ParseMode::Auto
35    }
36}
37
38impl FromStr for ParseMode {
39    type Err = anyhow::Error;
40
41    fn from_str(s: &str) -> anyhow::Result<Self> {
42        match s {
43            "wasm" => Ok(ParseMode::Wasm),
44            #[cfg(feature = "dwarf")]
45            "dwarf" => Ok(ParseMode::Dwarf),
46            "auto" => Ok(ParseMode::Auto),
47            _ => Err(anyhow!("Unknown parse mode: {}", s)),
48        }
49    }
50}
51
52/// The format of the output.
53#[derive(Clone, Copy, Debug)]
54pub enum OutputFormat {
55    /// Human readable text.
56    #[cfg(feature = "emit_text")]
57    Text,
58
59    // /// Hyper Text Markup Language.
60    // Html,
61    // /// Graphviz dot format.
62    // Dot,
63    /// Comma-separated values (CSV) format.
64    #[cfg(feature = "emit_csv")]
65    Csv,
66
67    /// JavaScript Object Notation format.
68    #[cfg(feature = "emit_json")]
69    Json,
70}
71
72#[cfg(feature = "emit_text")]
73#[cfg(feature = "emit_csv")]
74#[cfg(feature = "emit_json")]
75impl Default for OutputFormat {
76    fn default() -> OutputFormat {
77        OutputFormat::Text
78    }
79}
80
81impl FromStr for OutputFormat {
82    type Err = anyhow::Error;
83
84    fn from_str(s: &str) -> Result<Self, Self::Err> {
85        match s {
86            #[cfg(feature = "emit_text")]
87            "text" => Ok(OutputFormat::Text),
88            #[cfg(feature = "emit_json")]
89            "json" => Ok(OutputFormat::Json),
90            #[cfg(feature = "emit_csv")]
91            "csv" => Ok(OutputFormat::Csv),
92            _ => Err(anyhow!("Unknown output format: {}", s)),
93        }
94    }
95}
96
97/// Anything that can write itself in the given output format to the given
98/// destination.
99pub trait Emit {
100    /// Emit this thing to the given destination in the given output format.
101    fn emit(
102        &self,
103        items: &ir::Items,
104        destination: &mut dyn io::Write,
105        format: OutputFormat,
106    ) -> anyhow::Result<()> {
107        match format {
108            #[cfg(feature = "emit_text")]
109            OutputFormat::Text => self.emit_text(items, destination),
110            // OutputFormat::Html => self.emit_html(destination),
111            // OutputFormat::Dot => self.emit_dot(destination),
112            #[cfg(feature = "emit_csv")]
113            OutputFormat::Csv => self.emit_csv(items, destination),
114            #[cfg(feature = "emit_json")]
115            OutputFormat::Json => self.emit_json(items, destination),
116        }
117    }
118
119    /// Emit human readable text.
120    #[cfg(feature = "emit_text")]
121    fn emit_text(&self, items: &ir::Items, destination: &mut dyn io::Write) -> anyhow::Result<()>;
122
123    // /// Emit HTML.
124    // fn emit_html(&self, destination: &mut dyn io::Write) -> Result<(), Error>;
125
126    // /// Emit Graphviz's dot format.
127    // fn emit_dot(&self, destination: &mut dyn io::Write) -> Result<(), Error>;
128
129    /// Emit CSV.
130    #[cfg(feature = "emit_csv")]
131    fn emit_csv(&self, items: &ir::Items, destination: &mut dyn io::Write) -> anyhow::Result<()>;
132
133    /// Emit JSON.
134    #[cfg(feature = "emit_json")]
135    fn emit_json(&self, items: &ir::Items, destination: &mut dyn io::Write) -> anyhow::Result<()>;
136}