ogcapi_types/common/
landing_page.rs

1use serde::{Deserialize, Serialize};
2use serde_json::{Map, Value};
3
4#[cfg(feature = "edr")]
5use crate::edr::{Contact, Provider};
6
7use super::Links;
8
9/// The Landing page is the entry point of a OGC API
10///
11/// The Landing page provides links to:
12///
13/// * the API definition (link relations `service-desc` and `service-doc`),
14///
15/// * the Conformance declaration (path `/conformance`, link relation `conformance`), and
16///
17/// * the Collections (path `/collections`, link relation `data`).
18#[serde_with::skip_serializing_none]
19#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
20pub struct LandingPage {
21    /// Set to `Catalog` if this Catalog only implements the Catalog spec.
22    #[cfg(feature = "stac")]
23    #[serde(default = "crate::stac::catalog")]
24    pub r#type: String,
25    /// The STAC version the Catalog implements.
26    #[cfg(feature = "stac")]
27    #[serde(default = "crate::stac::stac_version")]
28    pub stac_version: String,
29    /// A list of extension identifiers the Catalog implements.
30    #[cfg(feature = "stac")]
31    #[serde(default)]
32    pub stac_extensions: Vec<String>,
33    /// Identifier for the Catalog.
34    #[cfg(feature = "stac")]
35    pub id: String,
36    /// The title of the API
37    pub title: Option<String>,
38    /// A textual description of the API
39    pub description: Option<String>,
40    /// The `attribution` should be short and intended for presentation to a
41    /// user, for example, in a corner of a map. Parts of the text can be links
42    /// to other resources if additional information is needed. The string can
43    /// include HTML markup.
44    pub attribution: Option<String>,
45    /// Links to the resources exposed through this API
46    #[serde(default)]
47    pub links: Links,
48    #[cfg(feature = "edr")]
49    #[serde(default, skip_serializing_if = "Vec::is_empty")]
50    pub keywords: Vec<String>,
51    #[cfg(feature = "edr")]
52    pub provider: Option<Provider>,
53    #[cfg(feature = "edr")]
54    pub contact: Option<Contact>,
55    #[cfg(feature = "stac")]
56    #[serde(default, rename = "conformsTo", skip_serializing_if = "Vec::is_empty")]
57    pub conforms_to: Vec<String>,
58    #[serde(flatten, default, skip_serializing_if = "Map::is_empty")]
59    pub additional_properties: Map<String, Value>,
60}
61
62#[allow(clippy::derivable_impls)]
63impl Default for LandingPage {
64    fn default() -> Self {
65        Self {
66            #[cfg(feature = "stac")]
67            r#type: crate::stac::catalog(),
68            #[cfg(feature = "stac")]
69            stac_version: crate::stac::stac_version(),
70            #[cfg(feature = "stac")]
71            stac_extensions: Default::default(),
72            #[cfg(feature = "stac")]
73            id: Default::default(),
74            title: Default::default(),
75            description: Default::default(),
76            attribution: Default::default(),
77            links: Default::default(),
78            #[cfg(feature = "edr")]
79            keywords: Default::default(),
80            #[cfg(feature = "edr")]
81            provider: Default::default(),
82            #[cfg(feature = "edr")]
83            contact: Default::default(),
84            #[cfg(feature = "stac")]
85            conforms_to: Default::default(),
86            additional_properties: Default::default(),
87        }
88    }
89}
90
91impl LandingPage {
92    pub fn new(name: impl ToString) -> Self {
93        let landing_page = LandingPage::default();
94        #[cfg(feature = "stac")]
95        let landing_page = landing_page.id(name.to_string());
96        landing_page.title(name)
97    }
98
99    #[cfg(feature = "stac")]
100    pub fn id(mut self, id: impl ToString) -> Self {
101        self.id = id.to_string();
102        self
103    }
104
105    pub fn title(mut self, title: impl ToString) -> Self {
106        self.title = Some(title.to_string());
107        self
108    }
109
110    pub fn description(mut self, description: impl ToString) -> Self {
111        self.description = Some(description.to_string());
112        self
113    }
114
115    pub fn links(mut self, links: Links) -> Self {
116        self.links = links;
117        self
118    }
119
120    #[cfg(feature = "stac")]
121    pub fn conforms_to(mut self, classes: &[impl ToString]) -> Self {
122        self.conforms_to = classes.iter().map(|c| c.to_string()).collect();
123        self
124    }
125}