use crate::model::HasInnerContent;
#[cfg(feature = "fmt_json")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub enum InlineContent {
HyperLink(HyperLink),
Image(Image),
Text(Text),
Math(Math),
Character(Character),
LineBreak,
Span(Span),
}
pub trait HasInlineContent: Default + HasInnerContent<InlineContent> {
fn link(inner: HyperLink) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_link(inner);
new_self
}
fn image(inner: Image) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_image(inner);
new_self
}
fn text(inner: Text) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_text(inner);
new_self
}
fn math(inner: Math) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_math(inner);
new_self
}
fn text_str(inner: &str) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_text(inner.into());
new_self
}
fn character(inner: Character) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_character(inner);
new_self
}
fn line_break() -> Self {
let mut new_self = Self::default();
let _ = new_self.add_line_break();
new_self
}
fn span(span: Span) -> Self {
let mut new_self = Self::default();
let _ = new_self.add_span(span);
new_self
}
fn add_link(&mut self, inner: HyperLink) -> &mut Self {
let _ = self.add_content(inner.into()).unwrap();
self
}
fn add_image(&mut self, inner: Image) -> &mut Self {
let _ = self.add_content(inner.into()).unwrap();
self
}
fn add_text(&mut self, inner: Text) -> &mut Self {
let _ = self.add_content(inner.into()).unwrap();
self
}
fn add_text_str(&mut self, inner: &str) -> &mut Self {
let t: Text = inner.into();
self.add_content(t.into()).unwrap();
self
}
fn add_math(&mut self, inner: Math) -> &mut Self {
let _ = self.add_content(inner.into()).unwrap();
self
}
fn add_character(&mut self, inner: Character) -> &mut Self {
self.add_content(inner.into()).unwrap();
self
}
fn add_space(&mut self) -> &mut Self {
self.add_content(Character::Space.into()).unwrap();
self
}
fn add_non_breaking_space(&mut self) -> &mut Self {
self.add_content(Character::NonBreakSpace.into()).unwrap();
self
}
fn add_line_break(&mut self) -> &mut Self {
self.add_content(InlineContent::LineBreak).unwrap();
self
}
fn add_span(&mut self, inner: Span) -> &mut Self {
self.add_content(InlineContent::Span(inner)).unwrap();
self
}
fn plain(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Plain))
}
fn plain_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Plain))
}
fn italic(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Italic))
}
fn italic_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Italic))
}
fn bold(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Bold))
}
fn bold_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Bold))
}
fn mono(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Mono))
}
fn mono_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Mono))
}
fn code(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Code))
}
fn code_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Code))
}
fn strikethrough(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Strikethrough))
}
fn strikethrough_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Strikethrough))
}
fn underline(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Underline))
}
fn underline_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Underline))
}
fn small_caps(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::SmallCaps))
}
fn small_caps_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::SmallCaps))
}
fn superscript(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Superscript))
}
fn superscript_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Superscript))
}
fn subscript(inner: InlineContent) -> Self {
Self::span(Span::inner_with_style(inner, SpanStyle::Subscript))
}
fn subscript_str(inner: &str) -> Self {
Self::span(Span::with_style(inner, SpanStyle::Subscript))
}
fn unformatted_string(&self) -> String {
let mut s = String::new();
let _ = unformat(&mut s, self.inner());
s
}
}
fn unformat(s: &mut String, content: &[InlineContent]) -> String {
for item in content {
match item {
InlineContent::Text(value) => s.push_str(value.inner()),
InlineContent::Character(value) => match value {
Character::Space => s.push(' '),
Character::NonBreakSpace => s.push(' '),
Character::Hyphen => s.push('-'),
Character::EmDash => s.push_str("---"),
Character::EnDash => s.push_str("--"),
Character::Emoji(e) => s.push_str(e.inner()),
Character::Other(c) => s.push(*c),
},
InlineContent::LineBreak => s.push('\n'),
InlineContent::Span(value) => {
let s2 = unformat(s, value.inner());
s.push_str(&s2)
}
_ => {}
}
}
s.clone()
}
#[doc(hidden)]
pub mod character;
pub use character::{Character, Emoji};
#[cfg(feature = "emoji_names")]
#[allow(missing_docs)]
pub mod emoji_names;
#[doc(hidden)]
pub mod image;
pub use image::Image;
#[doc(hidden)]
pub mod link;
pub use link::{HyperLink, HyperLinkTarget};
#[doc(hidden)]
pub mod math;
pub use math::Math;
#[doc(hidden)]
pub mod text;
pub use text::{Span, SpanStyle, Text};