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 {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
#[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 {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub content: Vec<InlineNode>,
#[serde(skip)]
pub number: u32,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Icon {
pub target: Source,
pub attributes: ElementAttributes,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Link {
#[serde(skip_serializing)]
pub text: Option<String>,
pub target: Source,
pub attributes: ElementAttributes,
pub location: Location,
}
impl Link {
#[must_use]
pub fn new(target: Source, location: Location) -> Self {
Self {
text: None,
target,
attributes: ElementAttributes::default(),
location,
}
}
#[must_use]
pub fn with_text(mut self, text: Option<String>) -> Self {
self.text = text;
self
}
#[must_use]
pub fn with_attributes(mut self, attributes: ElementAttributes) -> Self {
self.attributes = attributes;
self
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Url {
#[serde(skip_serializing)]
pub text: Vec<InlineNode>,
pub target: Source,
pub attributes: ElementAttributes,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Mailto {
#[serde(skip_serializing)]
pub text: Vec<InlineNode>,
pub target: Source,
pub attributes: ElementAttributes,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Button {
pub label: String,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Menu {
pub target: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub items: Vec<String>,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Keyboard {
pub keys: Vec<Key>,
pub location: Location,
}
impl Keyboard {
#[must_use]
pub fn new(keys: Vec<Key>, location: Location) -> Self {
Self { keys, location }
}
}
pub type Key = String;
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct CrossReference {
pub target: String,
#[serde(skip_serializing)]
pub text: Vec<InlineNode>,
pub location: Location,
}
impl CrossReference {
#[must_use]
pub fn new(target: impl Into<String>, location: Location) -> Self {
Self {
target: target.into(),
text: Vec::new(),
location,
}
}
#[must_use]
pub fn with_text(mut self, text: Vec<InlineNode>) -> Self {
self.text = text;
self
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Autolink {
pub url: Source,
#[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 {
pub content: String,
pub notation: StemNotation,
pub location: Location,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub enum IndexTermKind {
Flow(String),
Concealed {
term: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
secondary: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
tertiary: Option<String>,
},
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[non_exhaustive]
pub struct IndexTerm {
pub kind: IndexTermKind,
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.as_deref(),
}
}
#[must_use]
pub fn tertiary(&self) -> Option<&str> {
match &self.kind {
IndexTermKind::Flow(_) => None,
IndexTermKind::Concealed { tertiary, .. } => tertiary.as_deref(),
}
}
#[must_use]
pub fn is_visible(&self) -> bool {
matches!(self.kind, IndexTermKind::Flow(_))
}
}