use crate::error;
use crate::model::inline::Character;
use crate::model::inline::{HasInlineContent, InlineContent};
use crate::model::{HasInnerContent, HasStyles, Style};
#[cfg(feature = "fmt_json")]
use serde::{Deserialize, Serialize};
use std::ops::Deref;
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub enum SpanStyle {
Plain,
Italic,
Bold,
Mono,
Code,
Strikethrough,
Underline,
SmallCaps,
Superscript,
Subscript,
Sized(Size),
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub enum Size {
Largest,
Larger,
Large,
Normal,
Small,
Smaller,
Smallest,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Span {
inner: Vec<InlineContent>,
#[cfg_attr(feature = "fmt_json", serde(skip_serializing_if = "Vec::is_empty"))]
#[cfg_attr(feature = "fmt_json", serde(default))]
styles: Vec<SpanStyle>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Text(String);
impl Default for SpanStyle {
fn default() -> Self {
Self::Plain
}
}
impl Style for SpanStyle {}
impl Default for Size {
fn default() -> Self {
Self::Normal
}
}
impl Default for Text {
fn default() -> Self {
Self(String::new())
}
}
impl From<String> for Text {
fn from(s: String) -> Self {
Self(s)
}
}
impl From<&str> for Text {
fn from(s: &str) -> Self {
Self(s.to_string())
}
}
impl Deref for Text {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
inline_impls!(Text);
inner_impl!(Text, String);
impl Text {
pub fn new(s: &str) -> Self {
Self(s.to_string())
}
}
impl Default for Span {
fn default() -> Self {
Self {
inner: Default::default(),
styles: Default::default(),
}
}
}
inline_impls!(Span);
has_inline_impls!(Span);
has_styles_impls!(Span, SpanStyle);
impl Span {
pub fn with_style(inner: &str, style: SpanStyle) -> Self {
Self {
inner: vec![Text::from(inner).into()],
styles: vec![style],
}
}
pub fn with_styles(inner: &str, styles: Vec<SpanStyle>) -> Self {
Self {
inner: vec![Text::from(inner).into()],
styles,
}
}
pub fn inner_with_style(inner: InlineContent, style: SpanStyle) -> Self {
Self {
inner: vec![inner],
styles: vec![style],
}
}
pub fn inner_with_styles(inner: InlineContent, styles: Vec<SpanStyle>) -> Self {
Self {
inner: vec![inner],
styles,
}
}
pub fn space() -> Self {
Self::from(InlineContent::from(Character::Space.into()))
}
}