use crate::error::Error as GoogleMapsError;
use phf::phf_map;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[repr(u8)]
#[non_exhaustive]
pub enum Field {
AddressComponent = 0,
AdrAddress = 1,
BusinessStatus = 2,
FormattedAddress = 3,
Geometry = 4,
Icon = 5,
IconMaskBaseUri = 6,
IconBackgroundColor = 8,
#[default] Name = 9,
Photo = 10,
PlaceId = 11,
PlusCode = 12,
Type = 13,
Url = 14,
UtcOffset = 15,
Vicinity = 16,
WheelchairAccessibleEntrance = 17,
CurrentOpeningHours = 18,
FormattedPhoneNumber = 19,
InternationalPhoneNumber = 20,
OpeningHours = 21,
SecondaryOpeningHours = 22,
Website = 23,
CurbsidePickup = 24,
Delivery = 25,
DineIn = 26,
EditorialSummary = 27,
PriceLevel = 28,
Rating = 29,
Reservable = 30,
Reviews = 31,
ServesBeer = 32,
ServesBreakfast = 33,
ServesBrunch = 34,
ServesLunch = 35,
ServesVegetarianFood = 36,
ServesWine = 37,
Takeout = 38,
UserRatingsTotal = 39,
Other(String) = 40,
}
impl<'de> Deserialize<'de> for Field {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let string = String::deserialize(deserializer)?;
match Self::try_from(string.as_str()) {
Ok(variant) => Ok(variant),
Err(error) => Err(serde::de::Error::custom(error.to_string())),
} } }
impl Serialize for Field {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(std::convert::Into::<&str>::into(self))
} }
impl<'a> std::convert::From<&'a Field> for &'a str {
fn from(field: &'a Field) -> Self {
match field {
Field::AddressComponent => "address_component",
Field::AdrAddress => "adr_address",
Field::BusinessStatus => "business_status",
Field::FormattedAddress => "formatted_address",
Field::Geometry => "geometry",
Field::Icon => "icon",
Field::IconMaskBaseUri => "icon_mask_base_uri",
Field::IconBackgroundColor => "icon_background_color",
Field::Name => "name",
Field::Photo => "photo",
Field::PlaceId => "place_id",
Field::PlusCode => "plus_code",
Field::Type => "type",
Field::Url => "url",
Field::UtcOffset => "utc_offset",
Field::Vicinity => "vicinity",
Field::WheelchairAccessibleEntrance => "wheelchair_accessible_entrance",
Field::CurrentOpeningHours => "current_opening_hours",
Field::FormattedPhoneNumber => "formatted_phone_number",
Field::InternationalPhoneNumber => "international_phone_number",
Field::OpeningHours => "opening_hours",
Field::SecondaryOpeningHours => "secondary_opening_hours",
Field::Website => "website",
Field::CurbsidePickup => "curbside_pickup",
Field::Delivery => "delivery",
Field::DineIn => "dine_in",
Field::EditorialSummary => "editorial_summary",
Field::PriceLevel => "price_level",
Field::Rating => "rating",
Field::Reservable => "reservable",
Field::Reviews => "reviews",
Field::ServesBeer => "serves_beer",
Field::ServesBreakfast => "serves_breakfast",
Field::ServesBrunch => "serves_brunch",
Field::ServesLunch => "serves_lunch",
Field::ServesVegetarianFood => "serves_vegetarian_food",
Field::ServesWine => "serves_wine",
Field::Takeout => "takeout",
Field::UserRatingsTotal => "user_ratings_total",
Field::Other(string) => string,
} } }
impl std::fmt::Display for Field {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", std::convert::Into::<&str>::into(self))
} }
impl std::convert::From<&Self> for Field {
fn from(field: &Self) -> Self {
field.clone()
} }
impl std::convert::From<&Field> for String {
fn from(field: &Field) -> Self {
std::convert::Into::<&str>::into(field).to_string()
} }
static FIELD_TYPES_BY_CODE: phf::Map<&'static str, Field> = phf_map! {
"address_component" => Field::AddressComponent,
"adr_address" => Field::AdrAddress,
"business_status" => Field::BusinessStatus,
"formatted_address" => Field::FormattedAddress,
"geometry" => Field::Geometry,
"icon" => Field::Icon,
"icon_mask_base_uri" => Field::IconMaskBaseUri,
"icon_background_color" => Field::IconBackgroundColor,
"name" => Field::Name,
"photo" => Field::Photo,
"place_id" => Field::PlaceId,
"plus_code" => Field::PlusCode,
"type" => Field::Type,
"url" => Field::Url,
"utc_offset" => Field::UtcOffset,
"vicinity" => Field::Vicinity,
"wheelchair_accessible_entrance" => Field::WheelchairAccessibleEntrance,
"current_opening_hours" => Field::CurrentOpeningHours,
"formatted_phone_number" => Field::FormattedPhoneNumber,
"international_phone_number" => Field::InternationalPhoneNumber,
"opening_hours" => Field::OpeningHours,
"secondary_opening_hours" => Field::SecondaryOpeningHours,
"website" => Field::Website,
"curbside_pickup" => Field::CurbsidePickup,
"delivery" => Field::Delivery,
"dine_in" => Field::DineIn,
"editorial_summary" => Field::EditorialSummary,
"price_level" => Field::PriceLevel,
"rating" => Field::Rating,
"reservable" => Field::Reservable,
"reviews" => Field::Reviews,
"serves_beer" => Field::ServesBeer,
"serves_breakfast" => Field::ServesBreakfast,
"serves_brunch" => Field::ServesBrunch,
"serves_lunch" => Field::ServesLunch,
"serves_vegetarian_food" => Field::ServesVegetarianFood,
"serves_wine" => Field::ServesWine,
"takeout" => Field::Takeout,
"user_ratings_total" => Field::UserRatingsTotal,
};
impl std::convert::TryFrom<&str> for Field {
type Error = GoogleMapsError;
fn try_from(field_code: &str) -> Result<Self, Self::Error> {
Ok(FIELD_TYPES_BY_CODE
.get(field_code)
.cloned()
.unwrap_or_else(|| Self::Other(field_code.to_string())))
} }
impl std::str::FromStr for Field {
type Err = GoogleMapsError;
fn from_str(field_code: &str) -> Result<Self, Self::Err> {
Ok(FIELD_TYPES_BY_CODE
.get(field_code)
.cloned()
.unwrap_or_else(|| Self::Other(field_code.to_string())))
} }
impl Field {
#[must_use]
pub fn display(&self) -> &str {
match self {
Self::AddressComponent => "Address Component",
Self::AdrAddress => "adr Address",
Self::BusinessStatus => "Business Status",
Self::FormattedAddress => "Formatted Address",
Self::Geometry => "Geometry",
Self::Icon => "Icon",
Self::IconMaskBaseUri => "Icon Mask Base URI",
Self::IconBackgroundColor => "Icon Background Color",
Self::Name => "Name",
Self::Photo => "Photo",
Self::PlaceId => "Place ID",
Self::PlusCode => "Plus Code",
Self::Type => "Type",
Self::Url => "URL",
Self::UtcOffset => "UTC Offset",
Self::Vicinity => "Vicinity",
Self::WheelchairAccessibleEntrance => "Wheelchair Accessible Entrance",
Self::CurrentOpeningHours => "Current Opening Hours",
Self::FormattedPhoneNumber => "Formatted Phone Number",
Self::InternationalPhoneNumber => "International Phone Number",
Self::OpeningHours => "Opening Hours",
Self::SecondaryOpeningHours => "Secondary Opening Hours",
Self::Website => "Website",
Self::CurbsidePickup => "Curbside Pickup",
Self::Delivery => "Delivery",
Self::DineIn => "Dine In",
Self::EditorialSummary => "Editorial Summary",
Self::PriceLevel => "Price Level",
Self::Rating => "Rating",
Self::Reservable => "Reservable",
Self::Reviews => "Reviews",
Self::ServesBeer => "Serves Beer",
Self::ServesBreakfast => "Serves Breakfast",
Self::ServesBrunch => "Serves Brunch",
Self::ServesLunch => "Serves Lunch",
Self::ServesVegetarianFood => "Serves Vegetarian Food",
Self::ServesWine => "Serves Wine",
Self::Takeout => "Takeout",
Self::UserRatingsTotal => "User Ratings Total",
Self::Other(string) => string,
} } }
impl Field {
pub fn vec_to_csv(fields: &[Self]) -> String {
fields
.iter()
.map(String::from)
.collect::<Vec<String>>()
.join(",")
}
}