use crate::places_new::autocomplete::response::{FormattableText, StructuredFormat};
use crate::places_new::PlaceType;
use rust_decimal::{Decimal, prelude::FromPrimitive};
#[derive(
// std
Clone,
Debug,
Eq,
PartialEq,
// serde
serde::Deserialize,
serde::Serialize,
// getset
getset::Getters,
getset::MutGetters,
getset::Setters,
)]
#[serde(rename_all = "camelCase")]
pub struct PlacePrediction {
pub place: String,
#[serde(rename = "placeId")]
pub place_id: String,
pub text: FormattableText,
#[serde(rename = "structuredFormat", skip_serializing_if = "Option::is_none")]
pub structured_format: Option<StructuredFormat>,
#[serde(default)]
pub types: Vec<PlaceType>,
#[serde(rename = "distanceMeters", skip_serializing_if = "Option::is_none")]
pub distance_meters: Option<i32>,
}
impl PlacePrediction {
#[must_use]
pub const fn new(
place: String,
place_id: String,
text: FormattableText,
structured_format: Option<StructuredFormat>,
types: Vec<PlaceType>,
distance_meters: Option<i32>,
) -> Self {
Self {
place,
place_id,
text,
structured_format,
types,
distance_meters,
}
}
#[must_use]
pub fn place(&self) -> &str {
&self.place
}
#[must_use]
pub fn place_id(&self) -> &str {
&self.place_id
}
#[must_use]
pub const fn text(&self) -> &FormattableText {
&self.text
}
#[must_use]
pub const fn structured_format(&self) -> Option<&StructuredFormat> {
self.structured_format.as_ref()
}
#[must_use]
pub fn types(&self) -> &[PlaceType] {
&self.types
}
#[must_use]
pub const fn distance_meters(&self) -> Option<i32> {
self.distance_meters
}
#[must_use]
pub fn distance_decimal(&self) -> Option<Decimal> {
self.distance_meters
.and_then(Decimal::from_i32)
}
#[must_use]
pub const fn has_structured_format(&self) -> bool {
self.structured_format.is_some()
}
#[must_use]
pub const fn has_distance(&self) -> bool {
self.distance_meters.is_some()
}
#[must_use]
pub fn to_html(&self, tag: &str) -> String {
self.text.to_html(tag)
}
#[must_use]
pub fn to_html_structured(&self, main_tag: &str, secondary_tag: &str) -> String {
self.structured_format
.as_ref()
.map_or_else(
|| self.text.to_html(main_tag),
|format| format.combined_html(main_tag, secondary_tag)
)
}
#[must_use]
pub fn format_with<F>(&self, formatter: F) -> String
where
F: FnMut(&str, bool) -> String,
{
self.text.format_with(formatter)
}
#[must_use]
pub fn format_with_structured<F, G>(&self, main_formatter: F, secondary_formatter: G) -> String
where
F: FnMut(&str, bool) -> String,
G: FnMut(&str, bool) -> String,
{
match &self.structured_format {
Some(format) => format.combined_format_with(main_formatter, secondary_formatter),
None => self.text.format_with(main_formatter),
}
}
}
impl std::fmt::Display for PlacePrediction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.text)
}
}