Skip to main content

hara_native/lang/data/
metadata.rs

1use 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}