use topcoat::{context::Cx, icon::IconData, view::Attributes};
pub(crate) fn runtime_link(cx: &Cx, href: &str) -> Attributes {
topcoat::runtime::link_attrs(cx, href.to_string(), topcoat::runtime::prefetch_mode(cx))
}
#[derive(Clone, Default, PartialEq, Eq)]
pub enum NavTarget {
#[default]
Derived,
Url(String),
}
impl NavTarget {
pub fn url(&self) -> Option<&str> {
match self {
Self::Derived => None,
Self::Url(url) => Some(url),
}
}
}
impl std::fmt::Debug for NavTarget {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Derived => f.write_str("Derived"),
Self::Url(url) => f.debug_tuple("Url").field(url).finish(),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct NavigationItem {
pub label: String,
pub target: NavTarget,
pub order: i32,
pub icon: Option<IconData>,
}
impl NavigationItem {
pub fn at(label: impl Into<String>, url: impl Into<String>) -> Self {
Self {
label: label.into(),
target: NavTarget::Url(url.into()),
order: 0,
icon: None,
}
}
#[must_use]
pub fn icon(mut self, icon: IconData) -> Self {
self.icon = Some(icon);
self
}
pub(crate) fn resolved(mut self, url: &str) -> Self {
if matches!(self.target, NavTarget::Derived) {
self.target = NavTarget::Url(url.to_string());
}
self
}
pub fn url(&self) -> Option<&str> {
self.target.url()
}
pub fn is_current_path(&self, current_path: &str) -> bool {
let Some(url) = self.url() else {
return false;
};
if current_path == url {
return true;
}
current_path
.strip_prefix(url)
.is_some_and(|rest| rest.starts_with('/'))
}
}
#[cfg(test)]
mod tests;