use crate::places_new::autocomplete::response::FormattableText;
#[derive(
// std
Clone,
Debug,
Eq,
PartialEq,
// serde
serde::Deserialize,
serde::Serialize,
// getset
getset::Getters,
getset::MutGetters,
getset::Setters,
)]
#[serde(rename_all = "camelCase")]
pub struct StructuredFormat {
#[getset(set = "pub", get_mut = "pub")]
pub main_text: FormattableText,
#[getset(set = "pub", get_mut = "pub")]
pub secondary_text: Option<FormattableText>,
}
impl StructuredFormat {
#[must_use]
pub const fn new(main_text: FormattableText, secondary_text: Option<FormattableText>) -> Self {
Self {
main_text,
secondary_text,
}
}
#[must_use]
pub const fn new_main_only(main_text: FormattableText) -> Self {
Self {
main_text,
secondary_text: None,
}
}
#[must_use]
pub const fn main_text(&self) -> &FormattableText {
&self.main_text
}
#[must_use]
pub const fn secondary_text(&self) -> Option<&FormattableText> {
self.secondary_text.as_ref()
}
#[must_use]
pub const fn has_secondary_text(&self) -> bool {
self.secondary_text.is_some()
}
#[must_use]
pub fn combined_text(&self) -> String {
self.secondary_text
.as_ref()
.map_or_else(
|| self.main_text.text().clone(),
|secondary| format!(
"{main}, {secondary}",
main = self.main_text.text(),
secondary = secondary.text()
)
)
}
#[must_use]
pub fn main_html(&self, tag: &str) -> String {
self.main_text.to_html(tag)
}
#[must_use]
pub fn secondary_html(&self, tag: &str) -> Option<String> {
self.secondary_text.as_ref().map(|text| text.to_html(tag))
}
#[must_use]
pub fn combined_html(&self, main_tag: &str, secondary_tag: &str) -> String {
self.secondary_text
.as_ref()
.map_or_else(
|| self.main_text.to_html(main_tag),
|secondary| format!(
"{main}, {secondary}",
main = self.main_text.to_html(main_tag),
secondary = secondary.to_html(secondary_tag)
))
}
#[must_use]
pub fn main_format_with<F>(&self, formatter: F) -> String
where
F: FnMut(&str, bool) -> String,
{
self.main_text.format_with(formatter)
}
#[must_use]
pub fn secondary_format_with<F>(&self, formatter: F) -> Option<String>
where
F: FnMut(&str, bool) -> String,
{
self.secondary_text
.as_ref()
.map(|text| text.format_with(formatter))
}
#[must_use]
#[allow(clippy::similar_names)]
pub fn combined_format_with<F, G>(&self, mut main_formatter: F, secondary_formatter: G) -> String
where
F: FnMut(&str, bool) -> String,
G: FnMut(&str, bool) -> String,
{
let main_formatted = self.main_text.format_with(&mut main_formatter);
match &self.secondary_text {
Some(secondary) => {
format!(
"{main}, {secondary}",
main = main_formatted,
secondary = secondary.format_with(secondary_formatter)
)
}
None => main_formatted,
}
}
}
impl std::fmt::Display for StructuredFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.combined_text())
}
}