1use crate::format_option;
30use crate::resources::storage::StringStorage;
31use crate::v2_0::attributes::Attributes;
32use std::fmt::{Display, Formatter};
33
34pub use crate::cityjson::core::metadata::{BBox, CRS, CityModelIdentifier, Date};
35
36#[derive(Clone, Default, Debug, PartialEq)]
38pub struct Metadata<SS: StringStorage> {
39 geographical_extent: Option<BBox>,
40 identifier: Option<CityModelIdentifier<SS>>,
41 point_of_contact: Option<Contact<SS>>,
42 reference_date: Option<Date<SS>>,
43 reference_system: Option<CRS<SS>>,
44 title: Option<SS::String>,
45 extra: Option<Attributes<SS>>,
46}
47
48impl<SS: StringStorage> Metadata<SS> {
49 #[must_use]
50 pub fn new() -> Self {
51 Self::default()
52 }
53
54 pub fn geographical_extent(&self) -> Option<&BBox> {
55 self.geographical_extent.as_ref()
56 }
57
58 pub fn identifier(&self) -> Option<&CityModelIdentifier<SS>> {
59 self.identifier.as_ref()
60 }
61
62 pub fn reference_date(&self) -> Option<&Date<SS>> {
63 self.reference_date.as_ref()
64 }
65
66 pub fn reference_system(&self) -> Option<&CRS<SS>> {
67 self.reference_system.as_ref()
68 }
69
70 pub fn title(&self) -> Option<&str> {
71 self.title.as_deref()
72 }
73
74 pub fn extra(&self) -> Option<&Attributes<SS>> {
75 self.extra.as_ref()
76 }
77
78 pub fn extra_mut(&mut self) -> &mut Attributes<SS> {
80 self.extra.get_or_insert_with(Attributes::new)
81 }
82
83 pub fn set_extra(&mut self, extra: Option<Attributes<SS>>) {
84 self.extra = extra;
85 }
86
87 pub fn set_geographical_extent(&mut self, bbox: BBox) {
88 self.geographical_extent = Some(bbox);
89 }
90
91 pub fn set_identifier(&mut self, identifier: CityModelIdentifier<SS>) {
92 self.identifier = Some(identifier);
93 }
94
95 pub fn set_reference_date(&mut self, date: Date<SS>) {
96 self.reference_date = Some(date);
97 }
98
99 pub fn set_reference_system(&mut self, crs: CRS<SS>) {
100 self.reference_system = Some(crs);
101 }
102
103 pub fn set_title(&mut self, title: SS::String) {
104 self.title = Some(title);
105 }
106
107 pub fn point_of_contact(&self) -> Option<&Contact<SS>> {
108 self.point_of_contact.as_ref()
109 }
110
111 pub fn set_point_of_contact(&mut self, contact: Option<Contact<SS>>) {
112 self.point_of_contact = contact;
113 }
114}
115
116impl<SS: StringStorage> std::fmt::Display for Metadata<SS> {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 write!(
119 f,
120 "geographical_extent: {}, identifier: {}, point_of_contact: {}, reference_date: {}, reference_system: {}, title: {}",
121 format_option(self.geographical_extent.as_ref()),
122 format_option(self.identifier.as_ref()),
123 format_option(self.point_of_contact.as_ref()),
124 format_option(self.reference_date.as_ref()),
125 format_option(self.reference_system.as_ref()),
126 format_option(self.title.as_ref())
127 )
128 }
129}
130
131#[derive(Clone, Default, Debug, PartialEq)]
135pub struct Contact<SS: StringStorage> {
136 name: SS::String,
137 email_address: SS::String,
138 role: Option<ContactRole>,
139 website: Option<SS::String>,
140 kind: Option<ContactType>,
141 address: Option<Attributes<SS>>,
142 phone: Option<SS::String>,
143 organization: Option<SS::String>,
144}
145
146impl<SS: StringStorage> Contact<SS> {
147 #[must_use]
148 pub fn new() -> Self {
149 Self::default()
150 }
151
152 #[must_use]
153 pub fn contact_name(&self) -> &str {
154 self.name.as_ref()
155 }
156
157 #[must_use]
158 pub fn email_address(&self) -> &str {
159 self.email_address.as_ref()
160 }
161
162 #[must_use]
163 pub fn role(&self) -> Option<ContactRole> {
164 self.role
165 }
166
167 #[must_use]
168 pub fn website(&self) -> &Option<SS::String> {
169 &self.website
170 }
171
172 #[must_use]
173 pub fn contact_type(&self) -> Option<ContactType> {
174 self.kind
175 }
176
177 #[must_use]
178 pub fn phone(&self) -> &Option<SS::String> {
179 &self.phone
180 }
181
182 #[must_use]
183 pub fn organization(&self) -> &Option<SS::String> {
184 &self.organization
185 }
186
187 pub fn set_contact_name(&mut self, contact_name: SS::String) {
188 self.name = contact_name;
189 }
190
191 pub fn set_email_address(&mut self, email_address: SS::String) {
192 self.email_address = email_address;
193 }
194
195 pub fn set_role(&mut self, role: Option<ContactRole>) {
196 self.role = role;
197 }
198
199 pub fn set_website(&mut self, website: Option<SS::String>) {
200 self.website = website;
201 }
202
203 pub fn set_contact_type(&mut self, contact_type: Option<ContactType>) {
204 self.kind = contact_type;
205 }
206
207 pub fn set_phone(&mut self, phone: Option<SS::String>) {
208 self.phone = phone;
209 }
210
211 pub fn set_organization(&mut self, organization: Option<SS::String>) {
212 self.organization = organization;
213 }
214
215 #[must_use]
216 pub fn address(&self) -> Option<&Attributes<SS>> {
217 self.address.as_ref()
218 }
219
220 pub fn address_mut(&mut self) -> &mut Attributes<SS> {
221 self.address.get_or_insert_with(Attributes::new)
222 }
223
224 pub fn set_address(&mut self, address: Option<Attributes<SS>>) {
225 self.address = address;
226 }
227}
228
229impl<SS: StringStorage> Display for Contact<SS> {
230 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
231 write!(
232 f,
233 "contact_name: {}, email_address: {}, role: {}, website: {}, contact_type: {}, address: {}, phone: {}, organization: {}",
234 self.name,
235 self.email_address,
236 format_option(self.role.as_ref()),
237 format_option(self.website.as_ref()),
238 format_option(self.kind.as_ref()),
239 format_option(self.address.as_ref()),
240 format_option(self.phone.as_ref()),
241 format_option(self.organization.as_ref())
242 )
243 }
244}
245
246#[repr(C)]
248#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
249pub enum ContactRole {
250 Author,
251 CoAuthor,
252 Processor,
253 PointOfContact,
254 Owner,
255 User,
256 Distributor,
257 Originator,
258 Custodian,
259 ResourceProvider,
260 RightsHolder,
261 Sponsor,
262 PrincipalInvestigator,
263 Stakeholder,
264 Publisher,
265}
266
267impl Display for ContactRole {
268 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
269 write!(f, "{self:?}")
270 }
271}
272
273#[repr(C)]
275#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
276pub enum ContactType {
277 Individual,
278 Organization,
279}
280
281impl Display for ContactType {
282 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
283 write!(f, "{self:?}")
284 }
285}