Skip to main content

webserver_base/templates/
site_entity.rs

1//! Who or what a site *is*, for schema.org.
2
3use serde::{Deserialize, Serialize};
4
5/// The entity behind a site, emitted as the `Person` or `Organization` node of
6/// the home page's JSON-LD graph.
7///
8/// Google uses this node — and especially its `sameAs` links — to reconcile a
9/// site with a known entity and to drive knowledge panels. Getting the type
10/// wrong is a factual claim about the world: a band is not a person, and a
11/// personal project is not a company.
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13pub enum SiteEntity {
14    /// A human being.
15    Person(String),
16    /// A company, band, or any other group.
17    Organization(String),
18}
19
20impl SiteEntity {
21    /// A site that represents a person.
22    #[must_use]
23    pub fn person(name: impl Into<String>) -> Self {
24        Self::Person(name.into())
25    }
26
27    /// A site that represents an organization.
28    #[must_use]
29    pub fn organization(name: impl Into<String>) -> Self {
30        Self::Organization(name.into())
31    }
32
33    /// The schema.org `@type`.
34    #[must_use]
35    pub const fn schema_type(&self) -> &'static str {
36        match self {
37            Self::Person(_) => "Person",
38            Self::Organization(_) => "Organization",
39        }
40    }
41
42    /// The entity's name.
43    #[must_use]
44    pub fn name(&self) -> &str {
45        match self {
46            Self::Person(name) | Self::Organization(name) => name,
47        }
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::SiteEntity;
54
55    #[test]
56    fn the_schema_type_follows_the_constructor_that_was_used() {
57        let expected: &str = "Person";
58        let actual: &str = SiteEntity::person("Todd Everett Griffin").schema_type();
59        assert_eq!(expected, actual);
60
61        let expected: &str = "Organization";
62        let actual: &str = SiteEntity::organization("Palms Small Engine").schema_type();
63        assert_eq!(expected, actual);
64    }
65
66    #[test]
67    fn the_name_survives_either_constructor() {
68        let expected: &str = "Triple Entendre";
69        let actual: SiteEntity = SiteEntity::organization("Triple Entendre");
70        assert_eq!(expected, actual.name());
71    }
72}