Skip to main content

mq_markdown/node/
attr_value.rs

1use crate::{Node, RenderOptions, node::values_to_string};
2
3pub mod attr_keys {
4    pub(crate) const IDENT: &str = "ident";
5    pub(crate) const LABEL: &str = "label";
6    pub(crate) const NAME: &str = "name";
7    pub(crate) const VALUE: &str = "value";
8    pub(crate) const VALUES: &str = "values";
9    pub(crate) const CHILDREN: &str = "children";
10    pub(crate) const TITLE: &str = "title";
11    pub(crate) const URL: &str = "url";
12    pub(crate) const ALT: &str = "alt";
13    pub(crate) const LANG: &str = "lang";
14    pub(crate) const META: &str = "meta";
15    pub(crate) const FENCE: &str = "fence";
16    pub(crate) const DEPTH: &str = "depth";
17    pub(crate) const LEVEL: &str = "level";
18    pub(crate) const INDEX: &str = "index";
19    pub(crate) const ALIGN: &str = "align";
20    pub(crate) const ORDERED: &str = "ordered";
21    pub(crate) const CHECKED: &str = "checked";
22    pub(crate) const COLUMN: &str = "column";
23    pub(crate) const ROW: &str = "row";
24}
25
26/// Represents a typed attribute value that can be returned from or passed to attr/set_attr methods.
27#[derive(Debug, Clone, PartialEq)]
28#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize), serde(untagged))]
29pub enum AttrValue {
30    Array(Vec<Node>),
31    String(String),
32    Number(f64),
33    Integer(i64),
34    Boolean(bool),
35    Null,
36}
37
38impl From<String> for AttrValue {
39    fn from(s: String) -> Self {
40        AttrValue::String(s)
41    }
42}
43
44impl From<&str> for AttrValue {
45    fn from(s: &str) -> Self {
46        AttrValue::String(s.to_string())
47    }
48}
49
50impl From<f64> for AttrValue {
51    fn from(n: f64) -> Self {
52        AttrValue::Number(n)
53    }
54}
55
56impl From<i64> for AttrValue {
57    fn from(n: i64) -> Self {
58        AttrValue::Integer(n)
59    }
60}
61
62impl From<i32> for AttrValue {
63    fn from(n: i32) -> Self {
64        AttrValue::Integer(n as i64)
65    }
66}
67
68impl From<usize> for AttrValue {
69    fn from(n: usize) -> Self {
70        AttrValue::Integer(n as i64)
71    }
72}
73
74impl From<u8> for AttrValue {
75    fn from(n: u8) -> Self {
76        AttrValue::Integer(n as i64)
77    }
78}
79
80impl From<bool> for AttrValue {
81    fn from(b: bool) -> Self {
82        AttrValue::Boolean(b)
83    }
84}
85
86impl AttrValue {
87    /// Converts the attribute value to a string representation.
88    pub fn as_string(&self) -> String {
89        match self {
90            AttrValue::String(s) => s.clone(),
91            AttrValue::Number(n) => n.to_string(),
92            AttrValue::Integer(i) => i.to_string(),
93            AttrValue::Boolean(b) => b.to_string(),
94            AttrValue::Array(arr) => values_to_string(arr, &RenderOptions::default()),
95            AttrValue::Null => String::new(),
96        }
97    }
98
99    /// Converts the attribute value to an integer representation.
100    pub fn as_i64(&self) -> Option<i64> {
101        match self {
102            AttrValue::String(s) => s.parse().ok(),
103            AttrValue::Number(n) => Some(*n as i64),
104            AttrValue::Integer(i) => Some(*i),
105            AttrValue::Boolean(b) => Some(*b as i64),
106            AttrValue::Array(arr) => Some(arr.len() as i64),
107            AttrValue::Null => None,
108        }
109    }
110
111    /// Converts the attribute value to a number representation.
112    pub fn as_f64(&self) -> Option<f64> {
113        match self {
114            AttrValue::String(s) => s.parse().ok(),
115            AttrValue::Number(n) => Some(*n),
116            AttrValue::Integer(i) => Some(*i as f64),
117            AttrValue::Boolean(_) => None,
118            AttrValue::Array(arr) => Some(arr.len() as f64),
119            AttrValue::Null => None,
120        }
121    }
122
123    /// Returns `true` if the attribute value is a string.
124    pub fn is_string(&self) -> bool {
125        matches!(self, AttrValue::String(_))
126    }
127
128    /// Returns `true` if the attribute value is a number.
129    pub fn is_number(&self) -> bool {
130        matches!(self, AttrValue::Number(_))
131    }
132
133    /// Returns `true` if the attribute value is an integer.
134    pub fn is_integer(&self) -> bool {
135        matches!(self, AttrValue::Integer(_))
136    }
137
138    /// Returns `true` if the attribute value is a boolean.
139    pub fn is_boolean(&self) -> bool {
140        matches!(self, AttrValue::Boolean(_))
141    }
142
143    /// Returns `true` if the attribute value is null.
144    pub fn is_null(&self) -> bool {
145        matches!(self, AttrValue::Null)
146    }
147}