hara_native/lang/data/
metadata.rs1use super::{Keyword, Symbol};
2use num_bigint::BigInt;
3use std::rc::Rc;
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum MetadataValue {
7 Nil,
8 Boolean(bool),
9 Number(i64),
10 Float(f64),
11 BigInteger(BigInt),
12 Character(char),
13 Regex(String),
14 Tagged(String, Box<MetadataValue>),
15 String(String),
16 Keyword(Keyword),
17 Symbol(Symbol),
18 Vector(Vec<MetadataValue>),
19 List(Vec<MetadataValue>),
20 Set(Vec<MetadataValue>),
21 Map(Vec<(MetadataValue, MetadataValue)>),
22}
23
24#[derive(Debug, Clone, Default, PartialEq)]
25pub struct Metadata {
26 entries: Vec<(MetadataValue, MetadataValue)>,
27}
28
29impl Metadata {
30 pub fn new(entries: Vec<(MetadataValue, MetadataValue)>) -> Rc<Self> {
31 Rc::new(Self { entries })
32 }
33
34 pub fn document(value: impl Into<String>) -> Rc<Self> {
35 Self::new(vec![(
36 MetadataValue::Keyword(Keyword::from("doc")),
37 MetadataValue::String(value.into()),
38 )])
39 }
40
41 pub fn entries(&self) -> &[(MetadataValue, MetadataValue)] {
42 &self.entries
43 }
44
45 pub fn get(&self, key: &MetadataValue) -> Option<&MetadataValue> {
46 self.entries
47 .iter()
48 .rev()
49 .find(|(candidate, _)| candidate == key)
50 .map(|(_, value)| value)
51 }
52
53 pub fn get_keyword(&self, key: &str) -> Option<&MetadataValue> {
54 self.get(&MetadataValue::Keyword(Keyword::from(key)))
55 }
56
57 pub fn flag(&self, key: &str) -> bool {
58 matches!(self.get_keyword(key), Some(MetadataValue::Boolean(true)))
59 }
60
61 pub fn doc(&self) -> Option<&str> {
62 match self.get_keyword("doc") {
63 Some(MetadataValue::String(value)) => Some(value),
64 _ => None,
65 }
66 }
67}