|
@@ -1,93 +1,10 @@
|
|
|
#![allow(non_snake_case)]
|
|
|
-use crate::core::Attributes;
|
|
|
-use derive_more::Display;
|
|
|
+
|
|
|
+use crate::{block_attribute, core::Attributes, ignore_attribute, inline_attribute};
|
|
|
use lazy_static::lazy_static;
|
|
|
+use serde::{Deserialize, Serialize};
|
|
|
use std::{collections::HashSet, fmt, fmt::Formatter, iter::FromIterator};
|
|
|
-
|
|
|
-lazy_static! {
|
|
|
- static ref BLOCK_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
|
|
|
- AttributeKey::Header,
|
|
|
- AttributeKey::LeftAlignment,
|
|
|
- AttributeKey::CenterAlignment,
|
|
|
- AttributeKey::RightAlignment,
|
|
|
- AttributeKey::JustifyAlignment,
|
|
|
- AttributeKey::Indent,
|
|
|
- AttributeKey::Align,
|
|
|
- AttributeKey::CodeBlock,
|
|
|
- AttributeKey::List,
|
|
|
- AttributeKey::Bullet,
|
|
|
- AttributeKey::Ordered,
|
|
|
- AttributeKey::Checked,
|
|
|
- AttributeKey::UnChecked,
|
|
|
- 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,]);
|
|
|
-}
|
|
|
-
|
|
|
-#[derive(Debug, PartialEq, Eq, Clone)]
|
|
|
-pub enum AttributeScope {
|
|
|
- Inline,
|
|
|
- Block,
|
|
|
- Embeds,
|
|
|
- Ignore,
|
|
|
-}
|
|
|
-
|
|
|
-macro_rules! inline_attribute {
|
|
|
- (
|
|
|
- $key: ident,
|
|
|
- $value: ty
|
|
|
- ) => {
|
|
|
- pub fn $key(value: $value) -> Self {
|
|
|
- Self {
|
|
|
- key: AttributeKey::$key,
|
|
|
- value: value.into(),
|
|
|
- scope: AttributeScope::Inline,
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-macro_rules! block_attribute {
|
|
|
- (
|
|
|
- $key: ident,
|
|
|
- $value: ident
|
|
|
- ) => {
|
|
|
- pub fn $key(value: $value) -> Self {
|
|
|
- Self {
|
|
|
- key: AttributeKey::$key,
|
|
|
- value: value.into(),
|
|
|
- scope: AttributeScope::Block,
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-macro_rules! ignore_attribute {
|
|
|
- (
|
|
|
- $key: ident,
|
|
|
- $value: ident
|
|
|
- ) => {
|
|
|
- pub fn $key(value: $value) -> Self {
|
|
|
- Self {
|
|
|
- key: AttributeKey::$key,
|
|
|
- value: value.into(),
|
|
|
- scope: AttributeScope::Ignore,
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
+use strum_macros::Display;
|
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct Attribute {
|
|
|
pub key: AttributeKey,
|
|
@@ -109,18 +26,14 @@ impl Attribute {
|
|
|
|
|
|
// block
|
|
|
block_attribute!(Header, usize);
|
|
|
- block_attribute!(LeftAlignment, usize);
|
|
|
- block_attribute!(CenterAlignment, usize);
|
|
|
- block_attribute!(RightAlignment, usize);
|
|
|
- block_attribute!(JustifyAlignment, bool);
|
|
|
- block_attribute!(Indent, String);
|
|
|
+ block_attribute!(Indent, usize);
|
|
|
block_attribute!(Align, String);
|
|
|
- block_attribute!(CodeBlock, String);
|
|
|
block_attribute!(List, String);
|
|
|
block_attribute!(Bullet, bool);
|
|
|
block_attribute!(Ordered, bool);
|
|
|
block_attribute!(Checked, bool);
|
|
|
block_attribute!(UnChecked, bool);
|
|
|
+ block_attribute!(CodeBlock, bool);
|
|
|
block_attribute!(QuoteBlock, bool);
|
|
|
|
|
|
// ignore
|
|
@@ -130,7 +43,7 @@ impl Attribute {
|
|
|
|
|
|
impl fmt::Display for Attribute {
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
|
- let s = format!("{:?}:{} {:?}", self.key, self.value.as_ref(), self.scope);
|
|
|
+ let s = format!("{:?}:{:?} {:?}", self.key, self.value.0, self.scope);
|
|
|
f.write_str(&s)
|
|
|
}
|
|
|
}
|
|
@@ -144,66 +57,56 @@ impl std::convert::Into<Attributes> for Attribute {
|
|
|
}
|
|
|
|
|
|
#[derive(Clone, Debug, Display, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
|
-#[serde(rename_all = "camelCase")]
|
|
|
+// serde.rs/variant-attrs.html
|
|
|
+// #[serde(rename_all = "snake_case")]
|
|
|
pub enum AttributeKey {
|
|
|
- #[display(fmt = "bold")]
|
|
|
+ #[serde(rename = "bold")]
|
|
|
Bold,
|
|
|
- #[display(fmt = "italic")]
|
|
|
+ #[serde(rename = "italic")]
|
|
|
Italic,
|
|
|
- #[display(fmt = "underline")]
|
|
|
+ #[serde(rename = "underline")]
|
|
|
Underline,
|
|
|
- #[display(fmt = "strike_through")]
|
|
|
+ #[serde(rename = "strikethrough")]
|
|
|
StrikeThrough,
|
|
|
- #[display(fmt = "font")]
|
|
|
+ #[serde(rename = "font")]
|
|
|
Font,
|
|
|
- #[display(fmt = "size")]
|
|
|
+ #[serde(rename = "size")]
|
|
|
Size,
|
|
|
- #[display(fmt = "link")]
|
|
|
+ #[serde(rename = "link")]
|
|
|
Link,
|
|
|
- #[display(fmt = "color")]
|
|
|
+ #[serde(rename = "color")]
|
|
|
Color,
|
|
|
- #[display(fmt = "background")]
|
|
|
+ #[serde(rename = "background")]
|
|
|
Background,
|
|
|
- #[display(fmt = "indent")]
|
|
|
+ #[serde(rename = "indent")]
|
|
|
Indent,
|
|
|
- #[display(fmt = "align")]
|
|
|
+ #[serde(rename = "align")]
|
|
|
Align,
|
|
|
- #[display(fmt = "code_block")]
|
|
|
+ #[serde(rename = "code_block")]
|
|
|
CodeBlock,
|
|
|
- #[display(fmt = "list")]
|
|
|
+ #[serde(rename = "list")]
|
|
|
List,
|
|
|
- #[display(fmt = "quote_block")]
|
|
|
+ #[serde(rename = "quote_block")]
|
|
|
QuoteBlock,
|
|
|
- #[display(fmt = "width")]
|
|
|
+ #[serde(rename = "width")]
|
|
|
Width,
|
|
|
- #[display(fmt = "height")]
|
|
|
+ #[serde(rename = "height")]
|
|
|
Height,
|
|
|
- #[display(fmt = "header")]
|
|
|
+ #[serde(rename = "header")]
|
|
|
Header,
|
|
|
- #[display(fmt = "left")]
|
|
|
- LeftAlignment,
|
|
|
- #[display(fmt = "center")]
|
|
|
- CenterAlignment,
|
|
|
- #[display(fmt = "right")]
|
|
|
- RightAlignment,
|
|
|
- #[display(fmt = "justify")]
|
|
|
- JustifyAlignment,
|
|
|
- #[display(fmt = "bullet")]
|
|
|
+ #[serde(rename = "bullet")]
|
|
|
Bullet,
|
|
|
- #[display(fmt = "ordered")]
|
|
|
+ #[serde(rename = "ordered")]
|
|
|
Ordered,
|
|
|
- #[display(fmt = "checked")]
|
|
|
+ #[serde(rename = "checked")]
|
|
|
Checked,
|
|
|
- #[display(fmt = "unchecked")]
|
|
|
+ #[serde(rename = "unchecked")]
|
|
|
UnChecked,
|
|
|
}
|
|
|
|
|
|
+// pub trait AttributeValueData<'a>: Serialize + Deserialize<'a> {}
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
|
|
-pub struct AttributeValue(pub(crate) String);
|
|
|
-
|
|
|
-impl AsRef<str> for AttributeValue {
|
|
|
- fn as_ref(&self) -> &str { &self.0 }
|
|
|
-}
|
|
|
+pub struct AttributeValue(pub(crate) Option<String>);
|
|
|
|
|
|
impl std::convert::From<&usize> for AttributeValue {
|
|
|
fn from(val: &usize) -> Self { AttributeValue::from(*val) }
|
|
@@ -212,19 +115,19 @@ impl std::convert::From<&usize> for AttributeValue {
|
|
|
impl std::convert::From<usize> for AttributeValue {
|
|
|
fn from(val: usize) -> Self {
|
|
|
if val > (0 as usize) {
|
|
|
- AttributeValue(format!("{}", val))
|
|
|
+ AttributeValue(Some(format!("{}", val)))
|
|
|
} else {
|
|
|
- AttributeValue(format!(""))
|
|
|
+ AttributeValue(None)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl std::convert::From<&str> for AttributeValue {
|
|
|
- fn from(val: &str) -> Self { AttributeValue(val.to_owned()) }
|
|
|
+ fn from(val: &str) -> Self { AttributeValue(Some(val.to_owned())) }
|
|
|
}
|
|
|
|
|
|
impl std::convert::From<String> for AttributeValue {
|
|
|
- fn from(val: String) -> Self { AttributeValue(val) }
|
|
|
+ fn from(val: String) -> Self { AttributeValue(Some(val)) }
|
|
|
}
|
|
|
|
|
|
impl std::convert::From<&bool> for AttributeValue {
|
|
@@ -234,10 +137,10 @@ impl std::convert::From<&bool> for AttributeValue {
|
|
|
impl std::convert::From<bool> for AttributeValue {
|
|
|
fn from(val: bool) -> Self {
|
|
|
let val = match val {
|
|
|
- true => "true",
|
|
|
- false => "",
|
|
|
+ true => Some("true".to_owned()),
|
|
|
+ false => None,
|
|
|
};
|
|
|
- AttributeValue(val.to_owned())
|
|
|
+ AttributeValue(val)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -247,3 +150,38 @@ pub fn is_block_except_header(k: &AttributeKey) -> bool {
|
|
|
}
|
|
|
BLOCK_KEYS.contains(k)
|
|
|
}
|
|
|
+
|
|
|
+lazy_static! {
|
|
|
+ static ref BLOCK_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
|
|
|
+ AttributeKey::Header,
|
|
|
+ AttributeKey::Indent,
|
|
|
+ AttributeKey::Align,
|
|
|
+ AttributeKey::CodeBlock,
|
|
|
+ AttributeKey::List,
|
|
|
+ AttributeKey::Bullet,
|
|
|
+ AttributeKey::Ordered,
|
|
|
+ AttributeKey::Checked,
|
|
|
+ AttributeKey::UnChecked,
|
|
|
+ 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,]);
|
|
|
+}
|
|
|
+
|
|
|
+#[derive(Debug, PartialEq, Eq, Clone)]
|
|
|
+pub enum AttributeScope {
|
|
|
+ Inline,
|
|
|
+ Block,
|
|
|
+ Embeds,
|
|
|
+ Ignore,
|
|
|
+}
|