wasm_metadata/oci_annotations/
homepage.rs1use std::borrow::Cow;
2use std::fmt::{self, Display};
3use std::str::FromStr;
4
5use anyhow::{ensure, Error, Result};
6use serde::Serialize;
7use url::Url;
8use wasm_encoder::{ComponentSection, CustomSection, Encode, Section};
9use wasmparser::CustomSectionReader;
10
11#[derive(Debug, Clone, PartialEq)]
13pub struct Homepage(CustomSection<'static>);
14
15impl Homepage {
16 pub fn new(s: &str) -> Result<Self> {
18 Ok(Url::parse(s)?.into())
19 }
20
21 pub(crate) fn parse_custom_section(reader: &CustomSectionReader<'_>) -> Result<Self> {
23 ensure!(
24 reader.name() == "homepage",
25 "The `homepage` custom section should have a name of 'homepage'"
26 );
27 let data = String::from_utf8(reader.data().to_owned())?;
28 Self::new(&data)
29 }
30}
31
32impl FromStr for Homepage {
33 type Err = Error;
34
35 fn from_str(s: &str) -> Result<Self, Self::Err> {
36 Self::new(s)
37 }
38}
39
40impl From<Url> for Homepage {
41 fn from(expression: Url) -> Self {
42 Self(CustomSection {
43 name: "homepage".into(),
44 data: Cow::Owned(expression.to_string().into_bytes()),
45 })
46 }
47}
48
49impl Serialize for Homepage {
50 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
51 where
52 S: serde::Serializer,
53 {
54 serializer.serialize_str(&self.to_string())
55 }
56}
57
58impl Display for Homepage {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 let data = String::from_utf8(self.0.data.to_vec()).unwrap();
63 write!(f, "{data}")
64 }
65}
66
67impl ComponentSection for Homepage {
68 fn id(&self) -> u8 {
69 ComponentSection::id(&self.0)
70 }
71}
72
73impl Section for Homepage {
74 fn id(&self) -> u8 {
75 Section::id(&self.0)
76 }
77}
78
79impl Encode for Homepage {
80 fn encode(&self, sink: &mut Vec<u8>) {
81 self.0.encode(sink);
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use wasm_encoder::Component;
89 use wasmparser::Payload;
90
91 #[test]
92 fn roundtrip() {
93 let mut component = Component::new();
94 component
95 .section(&Homepage::new("https://github.com/bytecodealliance/wasm-tools").unwrap());
96 let component = component.finish();
97
98 let mut parsed = false;
99 for section in wasmparser::Parser::new(0).parse_all(&component) {
100 if let Payload::CustomSection(reader) = section.unwrap() {
101 let description = Homepage::parse_custom_section(&reader).unwrap();
102 assert_eq!(
103 description.to_string(),
104 "https://github.com/bytecodealliance/wasm-tools"
105 );
106 parsed = true;
107 }
108 }
109 assert!(parsed);
110 }
111
112 #[test]
113 fn serialize() {
114 let description = Homepage::new("https://github.com/bytecodealliance/wasm-tools").unwrap();
115 let json = serde_json::to_string(&description).unwrap();
116 assert_eq!(r#""https://github.com/bytecodealliance/wasm-tools""#, json);
117 }
118}