wasm_metadata/
add_metadata.rs

1use crate::{
2    rewrite_wasm, Authors, 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 authors: Option<Authors>,
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.authors,
76            &self.description,
77            &self.licenses,
78            &self.source,
79            &self.homepage,
80            &self.revision,
81            &self.version,
82            input,
83        )
84    }
85}