wasm_metadata/
add_metadata.rs

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