link_preview/providers/
schema.rs1use scraper::{Html, Selector};
2
3pub enum SchemaMetaTag {
5 Name,
6 Description,
7 Image,
8}
9
10impl SchemaMetaTag {
11 fn str(&self) -> &str {
12 match self {
13 SchemaMetaTag::Name => "name",
14 SchemaMetaTag::Description => "description",
15 SchemaMetaTag::Image => "image",
16 }
17 }
18}
19
20pub fn find_schema_tag(html: &Html, tag: SchemaMetaTag) -> Option<String> {
22 let selector = Selector::parse(&format!("meta[itemprop=\"{}\"]", tag.str())).unwrap();
23
24 if let Some(element) = html.select(&selector).next() {
25 if let Some(value) = element.value().attr("content") {
26 return Some(value.to_string());
27 }
28 }
29
30 None
31}
32
33#[cfg(test)]
34mod tests {
35 use crate::html_from_bytes;
36 use crate::tests::SCHEMA_COMPLIANT_HTML;
37
38 use super::{find_schema_tag, SchemaMetaTag};
39
40 #[test]
41 fn retrieves_schema_name() {
42 let html = html_from_bytes(SCHEMA_COMPLIANT_HTML).unwrap();
43 let value = find_schema_tag(&html, SchemaMetaTag::Name).unwrap();
44
45 assert_eq!(value, "Schema.org tags are awesome");
46 }
47
48 #[test]
49 fn retrieves_schema_description() {
50 let html = html_from_bytes(SCHEMA_COMPLIANT_HTML).unwrap();
51 let value = find_schema_tag(&html, SchemaMetaTag::Description).unwrap();
52
53 assert_eq!(
54 value,
55 "Tips to set Schema.org tags like you have been doing it since year 1"
56 );
57 }
58
59 #[test]
60 fn retrieves_schema_image() {
61 let html = html_from_bytes(SCHEMA_COMPLIANT_HTML).unwrap();
62 let value = find_schema_tag(&html, SchemaMetaTag::Image).unwrap();
63
64 assert_eq!(value, "https://www.example.com/image.jpg");
65 }
66}