schemaorg_rs/profiles/google/
local_business.rs1use crate::types::SchemaNode;
7use crate::validation::ValidationDiagnostic as VD;
8
9use super::common::{recommend_property, require_property, validate_nested};
10use crate::profiles::{NodeProfileResult, Profile, TypeEligibility};
11
12pub struct GoogleLocalBusinessProfile;
17
18impl Profile for GoogleLocalBusinessProfile {
19 fn name(&self) -> &'static str {
20 "google"
21 }
22
23 fn version(&self) -> &'static str {
24 "2026-04-01"
25 }
26
27 fn source_url(&self) -> &'static str {
28 "https://developers.google.com/search/docs/appearance/structured-data/local-business"
29 }
30
31 fn supported_types(&self) -> &[&str] {
32 &["LocalBusiness"]
33 }
34
35 fn evaluate_node(&self, node: &SchemaNode, _vocab_diagnostics: &[VD]) -> NodeProfileResult {
36 let type_name = node.types.first().map_or("LocalBusiness", |t| t.as_str());
37 let path = type_name;
38 let mut diagnostics = Vec::new();
39 let mut required_missing = Vec::new();
40 let mut recommended_missing = Vec::new();
41
42 if let Some(d) = require_property(node, "name", path) {
44 required_missing.push("name".to_string());
45 diagnostics.push(d);
46 }
47 if let Some(d) = require_property(node, "address", path) {
48 required_missing.push("address".to_string());
49 diagnostics.push(d);
50 }
51
52 for prop in &[
54 "image",
55 "telephone",
56 "url",
57 "openingHoursSpecification",
58 "geo",
59 "priceRange",
60 ] {
61 if let Some(d) = recommend_property(node, prop, path) {
62 recommended_missing.push((*prop).to_string());
63 diagnostics.push(d);
64 }
65 }
66
67 let address_diags = validate_nested(
69 node,
70 "address",
71 "PostalAddress",
72 &[
73 "streetAddress",
74 "addressLocality",
75 "postalCode",
76 "addressCountry",
77 ],
78 &["addressRegion"],
79 path,
80 );
81 diagnostics.extend(address_diags);
82
83 let eligible = required_missing.is_empty();
84
85 NodeProfileResult {
86 type_eligibility: TypeEligibility {
87 schema_type: type_name.to_string(),
88 eligible,
89 required_missing,
90 recommended_missing,
91 field_diagnostics: diagnostics,
92 },
93 }
94 }
95}