use crate::locale::{L10n, LangId};
use crate::{builder_fn, AutoDefault};
#[derive(AutoDefault, Clone, Debug)]
pub struct Attr<T>(Option<T>);
impl<T> Attr<T> {
pub fn empty() -> Self {
Self(None)
}
pub fn some(value: T) -> Self {
Self(Some(value))
}
#[builder_fn]
pub fn with_opt(mut self, opt: Option<T>) -> Self {
self.0 = opt;
self
}
#[builder_fn]
pub fn with_value(mut self, value: T) -> Self {
self.0 = Some(value);
self
}
#[builder_fn]
pub fn with_none(mut self) -> Self {
self.0 = None;
self
}
pub fn get(&self) -> Option<T>
where
T: Clone,
{
self.0.clone()
}
pub fn as_ref(&self) -> Option<&T> {
self.0.as_ref()
}
pub fn into_inner(self) -> Option<T> {
self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_none()
}
}
impl Attr<L10n> {
pub fn new(value: L10n) -> Self {
Self::some(value)
}
pub fn lookup(&self, language: &impl LangId) -> Option<String> {
self.0.as_ref()?.lookup(language)
}
pub fn value(&self, language: &impl LangId) -> String {
self.lookup(language).unwrap_or_default()
}
}
impl Attr<String> {
pub fn as_str(&self) -> Option<&str> {
self.0.as_deref()
}
}
#[derive(AutoDefault, Clone, Debug)]
pub struct AttrId(Attr<String>);
impl AttrId {
pub fn new(id: impl AsRef<str>) -> Self {
Self::default().with_id(id)
}
#[builder_fn]
pub fn with_id(mut self, id: impl AsRef<str>) -> Self {
let id = id.as_ref().trim();
if id.is_empty() {
self.0 = Attr::default();
} else {
self.0 = Attr::some(id.to_ascii_lowercase().replace(' ', "_"));
}
self
}
pub fn get(&self) -> Option<String> {
self.0.get()
}
pub fn as_str(&self) -> Option<&str> {
self.0.as_str()
}
pub fn into_inner(self) -> Option<String> {
self.0.into_inner()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(AutoDefault, Clone, Debug)]
pub struct AttrName(Attr<String>);
impl AttrName {
pub fn new(name: impl AsRef<str>) -> Self {
Self::default().with_name(name)
}
#[builder_fn]
pub fn with_name(mut self, name: impl AsRef<str>) -> Self {
let name = name.as_ref().trim();
if name.is_empty() {
self.0 = Attr::default();
} else {
self.0 = Attr::some(name.to_ascii_lowercase().replace(' ', "_"));
}
self
}
pub fn get(&self) -> Option<String> {
self.0.get()
}
pub fn as_str(&self) -> Option<&str> {
self.0.as_str()
}
pub fn into_inner(self) -> Option<String> {
self.0.into_inner()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(AutoDefault, Clone, Debug)]
pub struct AttrValue(Attr<String>);
impl AttrValue {
pub fn new(value: impl AsRef<str>) -> Self {
Self::default().with_str(value)
}
#[builder_fn]
pub fn with_str(mut self, value: impl AsRef<str>) -> Self {
let value = value.as_ref().trim();
if value.is_empty() {
self.0 = Attr::default();
} else {
self.0 = Attr::some(value.to_string());
}
self
}
pub fn get(&self) -> Option<String> {
self.0.get()
}
pub fn as_str(&self) -> Option<&str> {
self.0.as_str()
}
pub fn into_inner(self) -> Option<String> {
self.0.into_inner()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}