1use crate::{
2 rewrite_wasm, Author, Description, Homepage, Licenses, Producers, Revision, Source, Version,
3};
4
5use 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)]
13pub 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")]
61pub(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
67impl 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