use crate::error;
use crate::model::block::{BlockContent, Label};
use crate::model::inline::Text;
use crate::model::inline::{HasInlineContent, InlineContent};
use crate::model::{block::HasLabel, HasInnerContent};
#[cfg(feature = "fmt_json")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub enum ListKind {
Ordered,
Unordered,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct List {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
label: Option<Label>,
kind: ListKind,
inner: Vec<ListItem>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub enum ListItem {
List(List),
Item(Item),
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Item {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
label: Option<Label>,
inner: Vec<InlineContent>,
}
impl Default for ListKind {
fn default() -> Self {
Self::Unordered
}
}
impl Default for List {
fn default() -> Self {
Self::new(Default::default())
}
}
label_impl!(List);
block_impls!(List);
impl List {
pub fn new(kind: ListKind) -> Self {
Self {
label: None,
kind,
inner: Default::default(),
}
}
pub fn ordered() -> Self {
Self::new(ListKind::Ordered)
}
pub fn unordered() -> Self {
Self::new(ListKind::Unordered)
}
pub fn has_inner(&self) -> bool {
!self.inner.is_empty()
}
pub fn inner(&self) -> &Vec<ListItem> {
&self.inner
}
fn add_inner(&mut self, item: ListItem) -> &mut Self {
self.inner.push(item);
self
}
pub fn add_item(&mut self, item: Item) -> &mut Self {
self.add_inner(ListItem::Item(item))
}
pub fn add_item_str(&mut self, item: &str) -> &mut Self {
self.add_item_from(Text::from(item).into())
}
pub fn add_item_from(&mut self, item: InlineContent) -> &mut Self {
self.add_inner(ListItem::Item(item.into()))
}
pub fn add_sub_list(&mut self, item: List) -> &mut Self {
self.add_inner(ListItem::List(item))
}
pub fn is_ordered(&self) -> bool {
matches!(self.kind, ListKind::Ordered)
}
pub fn is_unordered(&self) -> bool {
matches!(self.kind, ListKind::Unordered)
}
pub fn kind(&self) -> &ListKind {
&self.kind
}
}
impl Default for Item {
fn default() -> Self {
Self {
label: None,
inner: Default::default(),
}
}
}
label_impl!(Item);
has_inline_impls!(Item);
impl From<List> for ListItem {
fn from(value: List) -> Self {
Self::List(value)
}
}
impl From<Item> for ListItem {
fn from(value: Item) -> Self {
Self::Item(value)
}
}
impl ListItem {
pub fn is_sub_list(&self) -> bool {
matches!(&self, Self::List(_))
}
pub fn is_item(&self) -> bool {
matches!(&self, Self::Item(_))
}
}