#![cfg_attr(docsrs, feature(doc_cfg))]
#[doc(hidden)]
pub mod internal {
pub struct MaybeStr<'a>(Option<&'a str>);
pub use stylance_macros::*;
fn join_opt_str_iter<'a, Iter>(iter: &mut Iter) -> String
where
Iter: Iterator<Item = &'a str> + Clone,
{
let Some(first) = iter.next() else {
return String::new();
};
let size = first.len() + iter.clone().map(|v| v.len() + 1).sum::<usize>();
let mut result = String::with_capacity(size);
result.push_str(first);
for v in iter {
result.push(' ');
result.push_str(v);
}
debug_assert_eq!(result.len(), size);
result
}
pub fn join_maybe_str_slice(slice: &[MaybeStr<'_>]) -> String {
let mut iter = slice.iter().flat_map(|c| c.0);
join_opt_str_iter(&mut iter)
}
impl<'a> From<&'a str> for MaybeStr<'a> {
fn from(value: &'a str) -> Self {
MaybeStr::<'a>(Some(value))
}
}
impl<'a> From<&'a String> for MaybeStr<'a> {
fn from(value: &'a String) -> Self {
MaybeStr::<'a>(Some(value.as_ref()))
}
}
impl<'a, T> From<Option<&'a T>> for MaybeStr<'a>
where
T: AsRef<str> + ?Sized,
{
fn from(value: Option<&'a T>) -> Self {
Self(value.map(AsRef::as_ref))
}
}
impl<'a, T> From<&'a Option<T>> for MaybeStr<'a>
where
T: AsRef<str>,
{
fn from(value: &'a Option<T>) -> Self {
Self(value.as_ref().map(AsRef::as_ref))
}
}
}
#[macro_export]
macro_rules! import_style {
($(#[$meta:meta])* $vis:vis $ident:ident, $str:expr) => {
$(#[$meta])* $vis mod $ident {
::stylance::internal::import_style_classes_rel!($str);
}
};
}
#[macro_export]
macro_rules! import_crate_style {
($(#[$meta:meta])* $vis:vis $ident:ident, $str:expr) => {
$(#[$meta])* $vis mod $ident {
::stylance::internal::import_style_classes!($str);
}
};
}
pub trait JoinClasses {
fn join_classes(self) -> String;
}
impl JoinClasses for &[internal::MaybeStr<'_>] {
fn join_classes(self) -> String {
internal::join_maybe_str_slice(self)
}
}
macro_rules! impl_join_classes_for_tuples {
(($($types:ident),*), ($($idx:tt),*)) => {
impl<'a, $($types),*> JoinClasses for ($($types,)*)
where
$($types: Into<internal::MaybeStr<'a>>),*
{
fn join_classes(self) -> String {
internal::join_maybe_str_slice([
$((self.$idx).into()),*
].as_slice())
}
}
};
}
impl_join_classes_for_tuples!(
(T1, T2), (0, 1)
);
impl_join_classes_for_tuples!(
(T1, T2, T3), (0, 1, 2)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4), (0, 1, 2, 3)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5), (0, 1, 2, 3, 4)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6), (0, 1, 2, 3, 4, 5)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7), (0, 1, 2, 3, 4, 5, 6)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8), (0, 1, 2, 3, 4, 5, 6, 7)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9),
(0, 1, 2, 3, 4, 5, 6, 7, 8)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
);
impl_join_classes_for_tuples!(
(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17),
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
);
#[macro_export]
macro_rules! classes {
() => { "" };
($($exp:expr),+$(,)?) => {
::stylance::JoinClasses::join_classes([$($exp.into()),*].as_slice())
};
}