use serde::Serialize;
use crate::{ElementAttributes, InlineNode, Location, Source, StemNotation, Substitution};
pub const ICON_SIZES: &[&str] = &["1x", "2x", "3x", "4x", "5x", "lg", "fw"];
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Pass<'a> {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub text: Option<&'a str>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub substitutions: Vec<Substitution>,
pub location: Location,
#[serde(skip)]
pub kind: PassthroughKind,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Default)]
pub enum PassthroughKind {
#[default]
Single,
Double,
Triple,
Macro,
AttributeRef,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Footnote<'a> {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<&'a str>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub content: Vec<InlineNode<'a>>,
#[serde(skip)]
pub number: u32,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Icon<'a> {
pub target: Source<'a>,
pub attributes: ElementAttributes<'a>,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Link<'a> {
#[serde(skip_serializing)]
pub text: Vec<InlineNode<'a>>,
pub target: Source<'a>,
pub attributes: ElementAttributes<'a>,
pub location: Location,
}
impl<'a> Link<'a> {
#[must_use]
pub fn new(target: Source<'a>, location: Location) -> Self {
Self {
text: Vec::new(),
target,
attributes: ElementAttributes::default(),
location,
}
}
#[must_use]
pub fn with_text(mut self, text: Vec<InlineNode<'a>>) -> Self {
self.text = text;
self
}
#[must_use]
pub fn with_attributes(mut self, attributes: ElementAttributes<'a>) -> Self {
self.attributes = attributes;
self
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Url<'a> {
#[serde(skip_serializing)]
pub text: Vec<InlineNode<'a>>,
pub target: Source<'a>,
pub attributes: ElementAttributes<'a>,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Mailto<'a> {
#[serde(skip_serializing)]
pub text: Vec<InlineNode<'a>>,
pub target: Source<'a>,
pub attributes: ElementAttributes<'a>,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Button<'a> {
pub label: &'a str,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Menu<'a> {
pub target: &'a str,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub items: Vec<&'a str>,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Keyboard<'a> {
pub keys: Vec<Key<'a>>,
pub location: Location,
}
impl<'a> Keyboard<'a> {
#[must_use]
pub fn new(keys: Vec<Key<'a>>, location: Location) -> Self {
Self { keys, location }
}
}
pub type Key<'a> = &'a str;
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct CrossReference<'a> {
pub target: &'a str,
#[serde(skip_serializing)]
pub text: Vec<InlineNode<'a>>,
pub location: Location,
}
impl<'a> CrossReference<'a> {
#[must_use]
pub fn new(target: &'a str, location: Location) -> Self {
Self {
target,
text: Vec::new(),
location,
}
}
#[must_use]
pub fn with_text(mut self, text: Vec<InlineNode<'a>>) -> Self {
self.text = text;
self
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Autolink<'a> {
pub url: Source<'a>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub bracketed: bool,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Stem<'a> {
pub content: &'a str,
pub notation: StemNotation,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub enum IndexTermKind<'a> {
Flow(&'a str),
Concealed {
term: &'a str,
#[serde(default, skip_serializing_if = "Option::is_none")]
secondary: Option<&'a str>,
#[serde(default, skip_serializing_if = "Option::is_none")]
tertiary: Option<&'a str>,
},
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct IndexTerm<'a> {
pub kind: IndexTermKind<'a>,
pub location: Location,
}
impl IndexTerm<'_> {
#[must_use]
pub fn term(&self) -> &str {
match &self.kind {
IndexTermKind::Flow(term) | IndexTermKind::Concealed { term, .. } => term,
}
}
#[must_use]
pub fn secondary(&self) -> Option<&str> {
match &self.kind {
IndexTermKind::Flow(_) => None,
IndexTermKind::Concealed { secondary, .. } => *secondary,
}
}
#[must_use]
pub fn tertiary(&self) -> Option<&str> {
match &self.kind {
IndexTermKind::Flow(_) => None,
IndexTermKind::Concealed { tertiary, .. } => *tertiary,
}
}
#[must_use]
pub fn is_visible(&self) -> bool {
matches!(self.kind, IndexTermKind::Flow(_))
}
}