#[macro_export]
macro_rules! str_enum {
(
$(#[$meta:meta])*
$vis:vis enum $name:ident {
$(
$(#[$vmeta:meta])*
$variant:ident = $val:expr
),+ $(,)?
}
) => {
$(#[$meta])*
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "bindings", derive(specta::Type))]
#[non_exhaustive]
$vis enum $name {
$(
$(#[$vmeta])*
#[cfg_attr(any(feature = "schema", feature = "bindings"), serde(rename = $val))]
$variant,
)+
#[doc = "Fallback for forward-compatibility."]
#[cfg_attr(feature = "schema", schemars(skip))]
#[cfg_attr(feature = "bindings", specta(skip))]
Unknown(String),
}
impl $name {
#[doc = "Returns the string value associated with this variant."]
#[must_use]
pub fn as_str(&self) -> &str {
match self {
$( Self::$variant => $val, )+
Self::Unknown(s) => s.as_str(),
}
}
}
impl serde::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> serde::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = $name;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(match value {
$( $val => $name::$variant, )+
_ => $name::Unknown(value.to_owned()),
})
}
}
deserializer.deserialize_str(Visitor)
}
}
}
}
#[macro_export]
macro_rules! dispatch_component {
($target:expr, |$inner:ident| $action:expr) => {
match $target {
$crate::template::TemplateComponent::Contributor($inner) => $action,
$crate::template::TemplateComponent::Date($inner) => $action,
$crate::template::TemplateComponent::Title($inner) => $action,
$crate::template::TemplateComponent::Number($inner) => $action,
$crate::template::TemplateComponent::Variable($inner) => $action,
$crate::template::TemplateComponent::Group($inner) => $action,
$crate::template::TemplateComponent::Term($inner) => $action,
}
};
}
#[macro_export]
macro_rules! merge_options {
($target:expr, $source:expr, $($field:ident),+ $(,)?) => {
$(
if $source.$field.is_some() {
$target.$field = $source.$field.clone();
}
)+
};
}
#[macro_export]
macro_rules! tc_contributor {
($role:ident, $form:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Contributor(
$crate::template::TemplateContributor {
contributor: $crate::template::ContributorRole::$role,
form: $crate::template::ContributorForm::$form,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_date {
($date_var:ident, $form:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Date(
$crate::template::TemplateDate {
date: $crate::template::DateVariable::$date_var,
form: $crate::template::DateForm::$form,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_title {
($title_type:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Title(
$crate::template::TemplateTitle {
title: $crate::template::TitleType::$title_type,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_number {
($num_var:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Number(
$crate::template::TemplateNumber {
number: $crate::template::NumberVariable::$num_var,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_variable {
($var:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Variable(
$crate::template::TemplateVariable {
variable: $crate::template::SimpleVariable::$var,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_term {
($term_var:ident $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Term(
$crate::template::TemplateTerm {
term: $crate::locale::GeneralTerm::$term_var,
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! tc_group {
([$($item:expr),* $(,)?] $(, $key:ident = $val:expr)*) => {
$crate::template::TemplateComponent::Group(
$crate::template::TemplateGroup {
group: vec![$($item),*],
rendering: $crate::template::Rendering {
$( $key: Some($val.into()), )*
..Default::default()
},
..Default::default()
}
)
};
}
#[macro_export]
macro_rules! ref_book {
($id:expr, $family:expr, $given:expr, $year:expr, $title:expr) => {
$crate::reference::InputReference::Monograph(::std::boxed::Box::new(
$crate::reference::Monograph {
id: Some($id.into()),
r#type: $crate::reference::MonographType::Book,
title: Some($crate::reference::Title::Single($title.to_string())),
author: Some($crate::reference::Contributor::StructuredName(
$crate::reference::StructuredName {
family: $crate::reference::MultilingualString::Simple($family.to_string()),
given: $crate::reference::MultilingualString::Simple($given.to_string()),
..Default::default()
},
)),
issued: $crate::reference::EdtfString($year.to_string()),
..Default::default()
},
))
};
}
#[macro_export]
macro_rules! ref_book_authors {
($id:expr, [$(($family:expr, $given:expr)),* $(,)?], $year:expr, $title:expr) => {{
let _authors: Vec<$crate::reference::Contributor> = vec![
$(
$crate::reference::Contributor::StructuredName(
$crate::reference::StructuredName {
family: $crate::reference::MultilingualString::Simple(
$family.to_string(),
),
given: $crate::reference::MultilingualString::Simple($given.to_string()),
..Default::default()
},
),
)*
];
$crate::reference::InputReference::Monograph(::std::boxed::Box::new(
$crate::reference::Monograph {
id: Some($id.into()),
r#type: $crate::reference::MonographType::Book,
title: Some($crate::reference::Title::Single($title.to_string())),
author: Some($crate::reference::Contributor::ContributorList(
$crate::reference::ContributorList(_authors),
)),
issued: $crate::reference::EdtfString($year.to_string()),
..Default::default()
},
))
}};
}
#[macro_export]
macro_rules! ref_article {
($id:expr, $family:expr, $given:expr, $year:expr, $title:expr) => {
$crate::reference::InputReference::SerialComponent(::std::boxed::Box::new(
$crate::reference::SerialComponent {
id: Some($id.into()),
r#type: $crate::reference::SerialComponentType::Article,
title: Some($crate::reference::Title::Single($title.to_string())),
author: Some($crate::reference::Contributor::StructuredName(
$crate::reference::StructuredName {
family: $crate::reference::MultilingualString::Simple($family.to_string()),
given: $crate::reference::MultilingualString::Simple($given.to_string()),
..Default::default()
},
)),
issued: $crate::reference::EdtfString($year.to_string()),
container: Some($crate::reference::WorkRelation::Embedded(
::std::boxed::Box::new($crate::reference::InputReference::Serial(
::std::boxed::Box::new($crate::reference::Serial {
r#type: $crate::reference::SerialType::AcademicJournal,
title: Some($crate::reference::Title::Single(String::new())),
..Default::default()
}),
)),
)),
..Default::default()
},
))
};
}
#[macro_export]
macro_rules! ref_article_authors {
($id:expr, [$(($family:expr, $given:expr)),* $(,)?], $year:expr, $title:expr) => {{
let _authors: Vec<$crate::reference::Contributor> = vec![
$(
$crate::reference::Contributor::StructuredName(
$crate::reference::StructuredName {
family: $crate::reference::MultilingualString::Simple(
$family.to_string(),
),
given: $crate::reference::MultilingualString::Simple($given.to_string()),
..Default::default()
},
),
)*
];
$crate::reference::InputReference::SerialComponent(::std::boxed::Box::new(
$crate::reference::SerialComponent {
id: Some($id.into()),
r#type: $crate::reference::SerialComponentType::Article,
title: Some($crate::reference::Title::Single($title.to_string())),
author: Some($crate::reference::Contributor::ContributorList(
$crate::reference::ContributorList(_authors),
)),
issued: $crate::reference::EdtfString($year.to_string()),
..Default::default()
},
))
}};
}
#[macro_export]
macro_rules! citation_locator {
($label:ident, $value:expr) => {
$crate::citation::CitationLocator::single(
$crate::citation::LocatorType::$label,
$value,
)
};
($l1:ident => $v1:expr, $l2:ident => $v2:expr $(, $lrest:ident => $vrest:expr)* $(,)?) => {
$crate::citation::CitationLocator::compound(vec![
$crate::citation::LocatorSegment::new(
$crate::citation::LocatorType::$l1,
$v1,
),
$crate::citation::LocatorSegment::new(
$crate::citation::LocatorType::$l2,
$v2,
),
$(
$crate::citation::LocatorSegment::new(
$crate::citation::LocatorType::$lrest,
$vrest,
)
),*
]).expect("compound locator macro requires at least two segments")
};
}
#[macro_export]
macro_rules! citation_item {
($id:expr $(, $key:ident = $val:expr)*) => {{
#[allow(unused_mut)]
let mut _item = $crate::citation::CitationItem {
id: $id.to_string(),
..Default::default()
};
$( citation_item!(@set _item, $key, $val); )*
_item
}};
(@set $item:ident, locator, $val:expr) => { $item.locator = Some($val); };
(@set $item:ident, prefix, $val:expr) => { $item.prefix = Some($val.to_string()); };
(@set $item:ident, suffix, $val:expr) => { $item.suffix = Some($val.to_string()); };
}
#[macro_export]
macro_rules! citation {
([$($item:expr),* $(,)?] $(, $key:ident = $val:expr)* $(,)?) => {
$crate::citation::Citation {
items: vec![$($item),*],
$($key: $val,)*
..Default::default()
}
};
}
#[macro_export]
macro_rules! cite {
($id:expr) => {
$crate::citation::Citation {
items: vec![$crate::citation::CitationItem {
id: $id.to_string(),
..Default::default()
}],
..Default::default()
}
};
($id:expr, $key:ident = $val:expr) => {
$crate::citation::Citation {
items: vec![$crate::citation::CitationItem {
id: $id.to_string(),
..Default::default()
}],
$key: $val,
..Default::default()
}
};
}
#[macro_export]
macro_rules! bib_map {
($($key:expr => $val:expr),* $(,)?) => {{
#[allow(unused_mut)]
let mut _map = indexmap::IndexMap::new();
$( _map.insert($key.to_string(), $val); )*
_map
}};
}