1 | use crate::{ |
2 | rewrite_wasm, Author, Description, Homepage, Licenses, Producers, Revision, Source, Version, |
3 | }; |
4 | |
5 | use anyhow::Result; |
6 | |
7 | /// Add metadata (module name, producers) to a WebAssembly file. |
8 | /// |
9 | /// Supports both core WebAssembly modules and components. In components, |
10 | /// metadata will be added to the outermost component. |
11 | #[cfg_attr (feature = "clap" , derive(clap::Parser))] |
12 | #[derive (Debug, Clone, Default)] |
13 | pub struct AddMetadata { |
14 | /// Add a module or component name to the names section |
15 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
16 | pub name: Option<String>, |
17 | |
18 | /// Add a programming language to the producers section |
19 | #[cfg_attr (feature = "clap" , clap(long, value_parser = parse_key_value, value_name = "NAME=VERSION" ))] |
20 | pub language: Vec<(String, String)>, |
21 | |
22 | /// Add a tool and its version to the producers section |
23 | #[cfg_attr (feature = "clap" , clap(long = "processed-by" , value_parser = parse_key_value, value_name="NAME=VERSION" ))] |
24 | pub processed_by: Vec<(String, String)>, |
25 | |
26 | /// Add an SDK and its version to the producers section |
27 | #[cfg_attr (feature="clap" , clap(long, value_parser = parse_key_value, value_name="NAME=VERSION" ))] |
28 | pub sdk: Vec<(String, String)>, |
29 | |
30 | /// Contact details of the people or organization responsible, |
31 | /// encoded as a freeform string. |
32 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
33 | pub author: Option<Author>, |
34 | |
35 | /// A human-readable description of the binary |
36 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
37 | pub description: Option<Description>, |
38 | |
39 | /// License(s) under which contained software is distributed as an SPDX License Expression. |
40 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
41 | pub licenses: Option<Licenses>, |
42 | |
43 | /// URL to get source code for building the image |
44 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
45 | pub source: Option<Source>, |
46 | |
47 | /// URL to find more information on the binary |
48 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
49 | pub homepage: Option<Homepage>, |
50 | |
51 | /// Source control revision identifier for the packaged software. |
52 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
53 | pub revision: Option<Revision>, |
54 | |
55 | /// Version of the packaged software |
56 | #[cfg_attr (feature = "clap" , clap(long, value_name = "NAME" ))] |
57 | pub version: Option<Version>, |
58 | } |
59 | |
60 | #[cfg (feature = "clap" )] |
61 | pub(crate) fn parse_key_value(s: &str) -> Result<(String, String)> { |
62 | s.split_once('=' ) |
63 | .map(|(k, v)| (k.to_owned(), v.to_owned())) |
64 | .ok_or_else(|| anyhow::anyhow!("expected KEY=VALUE" )) |
65 | } |
66 | |
67 | impl AddMetadata { |
68 | /// Process a WebAssembly binary. Supports both core WebAssembly modules, and WebAssembly |
69 | /// components. The module and component will have, at very least, an empty name and producers |
70 | /// section created. |
71 | pub fn to_wasm(&self, input: &[u8]) -> Result<Vec<u8>> { |
72 | rewrite_wasm( |
73 | &self.name, |
74 | &Producers::from_meta(self), |
75 | &self.author, |
76 | &self.description, |
77 | &self.licenses, |
78 | &self.source, |
79 | &self.homepage, |
80 | &self.revision, |
81 | &self.version, |
82 | input, |
83 | ) |
84 | } |
85 | } |
86 | |