use std::str::FromStr;
use time::Date;
use crate::{
activity::*, contact::*, email::EmailAddress, id::*, links::*, location::*, review::*,
revision::*,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlaceRoot {
pub id: Id,
pub license: String,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct OpeningHours(String);
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct OpeningHoursParseError;
impl OpeningHours {
pub const fn min_len() -> usize {
4
}
}
impl FromStr for OpeningHours {
type Err = OpeningHoursParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let trimmed = s.trim();
if trimmed.len() < Self::min_len() {
return Err(OpeningHoursParseError);
}
Ok(Self(trimmed.to_string()))
}
}
impl From<String> for OpeningHours {
fn from(from: String) -> Self {
let res = Self(from);
debug_assert_eq!(Ok(&res), res.0.as_str().parse().as_ref());
res
}
}
impl From<OpeningHours> for String {
fn from(from: OpeningHours) -> Self {
from.0
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlaceRevision {
pub revision: Revision,
pub created: Activity,
pub title: String,
pub description: String,
pub location: Location,
pub contact: Option<Contact>,
pub opening_hours: Option<OpeningHours>,
pub founded_on: Option<Date>,
pub links: Option<Links>,
pub tags: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Place {
pub id: Id,
pub license: String,
pub revision: Revision,
pub created: Activity,
pub title: String,
pub description: String,
pub location: Location,
pub contact: Option<Contact>,
pub opening_hours: Option<OpeningHours>,
pub founded_on: Option<Date>,
pub links: Option<Links>,
pub tags: Vec<String>,
}
impl Place {
pub fn strip_activity_details(self) -> Self {
Self {
created: self.created.anonymize(),
..self
}
}
pub fn strip_contact_details(self) -> Self {
Self {
contact: None,
..self
}
}
pub fn contact_email(&self) -> Option<&EmailAddress> {
self.contact.as_ref().and_then(|c| c.email.as_ref())
}
pub fn is_owned<'a>(&self, moderated_tags: impl IntoIterator<Item = &'a str>) -> bool {
moderated_tags
.into_iter()
.any(|moderated_tag| self.tags.iter().any(|tag| tag == moderated_tag))
}
}
impl From<(PlaceRoot, PlaceRevision)> for Place {
fn from(from: (PlaceRoot, PlaceRevision)) -> Self {
let (
PlaceRoot { id, license },
PlaceRevision {
revision,
created,
title,
description,
location,
contact,
opening_hours,
founded_on,
links,
tags,
},
) = from;
Self {
id,
license,
revision,
created,
title,
description,
location,
contact,
opening_hours,
founded_on,
links,
tags,
}
}
}
impl From<Place> for (PlaceRoot, PlaceRevision) {
fn from(from: Place) -> Self {
let Place {
id,
license,
revision,
created,
title,
description,
location,
contact,
opening_hours,
founded_on,
links,
tags,
} = from;
(
PlaceRoot { id, license },
PlaceRevision {
revision,
created,
title,
description,
location,
contact,
opening_hours,
founded_on,
links,
tags,
},
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PlaceHistory {
pub place: PlaceRoot,
pub revisions: Vec<(PlaceRevision, Vec<ReviewStatusLog>)>,
}