185 lines
4.8 KiB
Rust
Raw Normal View History

2021-09-13 15:51:13 +08:00
#![allow(non_snake_case)]
2021-09-15 15:01:24 +08:00
2021-09-16 09:30:51 +08:00
use crate::{block_attribute, core::Attributes, ignore_attribute, inline_attribute, list_attribute};
2021-08-16 23:07:40 +08:00
use lazy_static::lazy_static;
2021-09-16 12:35:55 +08:00
2021-08-16 23:07:40 +08:00
use std::{collections::HashSet, fmt, fmt::Formatter, iter::FromIterator};
2021-09-15 15:01:24 +08:00
use strum_macros::Display;
2021-08-16 23:07:40 +08:00
#[derive(Debug, Clone)]
pub struct Attribute {
pub key: AttributeKey,
pub value: AttributeValue,
pub scope: AttributeScope,
}
2021-09-13 15:51:13 +08:00
impl Attribute {
// inline
2021-09-13 15:51:13 +08:00
inline_attribute!(Bold, bool);
inline_attribute!(Italic, bool);
inline_attribute!(Underline, bool);
inline_attribute!(StrikeThrough, bool);
inline_attribute!(Link, &str);
inline_attribute!(Color, String);
inline_attribute!(Font, usize);
inline_attribute!(Size, usize);
inline_attribute!(Background, String);
// block
2021-09-13 15:51:13 +08:00
block_attribute!(Header, usize);
2021-09-15 15:01:24 +08:00
block_attribute!(Indent, usize);
2021-09-13 15:51:13 +08:00
block_attribute!(Align, String);
2021-09-16 09:30:51 +08:00
block_attribute!(List, &str);
2021-09-15 15:01:24 +08:00
block_attribute!(CodeBlock, bool);
2021-09-13 15:51:13 +08:00
block_attribute!(QuoteBlock, bool);
// ignore
2021-09-13 15:51:13 +08:00
ignore_attribute!(Width, usize);
ignore_attribute!(Height, usize);
2021-09-16 09:30:51 +08:00
// List extension
list_attribute!(Bullet, "bullet");
list_attribute!(Ordered, "ordered");
list_attribute!(Checked, "checked");
list_attribute!(UnChecked, "unchecked");
2021-09-13 15:51:13 +08:00
}
2021-08-16 23:07:40 +08:00
impl fmt::Display for Attribute {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2021-09-15 15:01:24 +08:00
let s = format!("{:?}:{:?} {:?}", self.key, self.value.0, self.scope);
2021-08-16 23:07:40 +08:00
f.write_str(&s)
}
}
impl std::convert::Into<Attributes> for Attribute {
fn into(self) -> Attributes {
let mut attributes = Attributes::new();
attributes.add(self);
attributes
}
}
#[derive(Clone, Debug, Display, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
2021-09-15 15:01:24 +08:00
// serde.rs/variant-attrs.html
// #[serde(rename_all = "snake_case")]
2021-08-16 23:07:40 +08:00
pub enum AttributeKey {
2021-09-15 15:01:24 +08:00
#[serde(rename = "bold")]
2021-08-16 23:07:40 +08:00
Bold,
2021-09-15 15:01:24 +08:00
#[serde(rename = "italic")]
2021-08-16 23:07:40 +08:00
Italic,
2021-09-15 15:01:24 +08:00
#[serde(rename = "underline")]
2021-08-16 23:07:40 +08:00
Underline,
2021-09-15 15:01:24 +08:00
#[serde(rename = "strikethrough")]
2021-08-16 23:07:40 +08:00
StrikeThrough,
2021-09-15 15:01:24 +08:00
#[serde(rename = "font")]
2021-08-16 23:07:40 +08:00
Font,
2021-09-15 15:01:24 +08:00
#[serde(rename = "size")]
2021-08-16 23:07:40 +08:00
Size,
2021-09-15 15:01:24 +08:00
#[serde(rename = "link")]
2021-08-16 23:07:40 +08:00
Link,
2021-09-15 15:01:24 +08:00
#[serde(rename = "color")]
2021-08-16 23:07:40 +08:00
Color,
2021-09-15 15:01:24 +08:00
#[serde(rename = "background")]
2021-08-16 23:07:40 +08:00
Background,
2021-09-15 15:01:24 +08:00
#[serde(rename = "indent")]
2021-08-16 23:07:40 +08:00
Indent,
2021-09-15 15:01:24 +08:00
#[serde(rename = "align")]
2021-08-16 23:07:40 +08:00
Align,
2021-09-15 15:01:24 +08:00
#[serde(rename = "code_block")]
2021-08-16 23:07:40 +08:00
CodeBlock,
2021-09-15 15:01:24 +08:00
#[serde(rename = "list")]
2021-08-16 23:07:40 +08:00
List,
2021-09-15 15:01:24 +08:00
#[serde(rename = "quote_block")]
2021-08-16 23:07:40 +08:00
QuoteBlock,
2021-09-15 15:01:24 +08:00
#[serde(rename = "width")]
2021-08-16 23:07:40 +08:00
Width,
2021-09-15 15:01:24 +08:00
#[serde(rename = "height")]
2021-08-16 23:07:40 +08:00
Height,
2021-09-15 15:01:24 +08:00
#[serde(rename = "header")]
2021-08-16 23:07:40 +08:00
Header,
}
2021-09-15 15:01:24 +08:00
// pub trait AttributeValueData<'a>: Serialize + Deserialize<'a> {}
2021-08-16 23:07:40 +08:00
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2021-09-15 15:01:24 +08:00
pub struct AttributeValue(pub(crate) Option<String>);
2021-08-16 23:07:40 +08:00
impl std::convert::From<&usize> for AttributeValue {
fn from(val: &usize) -> Self { AttributeValue::from(*val) }
2021-09-13 15:51:13 +08:00
}
impl std::convert::From<usize> for AttributeValue {
fn from(val: usize) -> Self {
if val > (0 as usize) {
2021-09-15 15:01:24 +08:00
AttributeValue(Some(format!("{}", val)))
2021-09-13 15:51:13 +08:00
} else {
2021-09-15 15:01:24 +08:00
AttributeValue(None)
2021-09-13 15:51:13 +08:00
}
}
2021-08-16 23:07:40 +08:00
}
impl std::convert::From<&str> for AttributeValue {
2021-09-16 09:30:51 +08:00
fn from(val: &str) -> Self { val.to_owned().into() }
2021-08-16 23:07:40 +08:00
}
2021-09-13 15:51:13 +08:00
impl std::convert::From<String> for AttributeValue {
fn from(val: String) -> Self {
if val.is_empty() {
AttributeValue(None)
} else {
AttributeValue(Some(val))
}
}
2021-09-13 15:51:13 +08:00
}
impl std::convert::From<&bool> for AttributeValue {
fn from(val: &bool) -> Self { AttributeValue::from(*val) }
}
2021-08-16 23:07:40 +08:00
impl std::convert::From<bool> for AttributeValue {
fn from(val: bool) -> Self {
let val = match val {
2021-09-15 15:01:24 +08:00
true => Some("true".to_owned()),
false => None,
2021-08-16 23:07:40 +08:00
};
2021-09-15 15:01:24 +08:00
AttributeValue(val)
2021-08-16 23:07:40 +08:00
}
}
2021-08-17 11:23:28 +08:00
pub fn is_block_except_header(k: &AttributeKey) -> bool {
if k == &AttributeKey::Header {
return false;
}
BLOCK_KEYS.contains(k)
}
2021-09-15 15:01:24 +08:00
lazy_static! {
static ref BLOCK_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
AttributeKey::Header,
AttributeKey::Indent,
AttributeKey::Align,
AttributeKey::CodeBlock,
AttributeKey::List,
AttributeKey::QuoteBlock,
]);
static ref INLINE_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
AttributeKey::Bold,
AttributeKey::Italic,
AttributeKey::Underline,
AttributeKey::StrikeThrough,
AttributeKey::Link,
AttributeKey::Color,
AttributeKey::Font,
AttributeKey::Size,
AttributeKey::Background,
]);
static ref INGORE_KEYS: HashSet<AttributeKey> =
HashSet::from_iter(vec![AttributeKey::Width, AttributeKey::Height,]);
2021-09-15 15:01:24 +08:00
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum AttributeScope {
Inline,
Block,
Embeds,
Ignore,
}