hara-native 0.1.13

HAL-free native host runtime and package launcher for Hara
Documentation
use super::{Keyword, Symbol};
use num_bigint::BigInt;
use std::rc::Rc;

#[derive(Debug, Clone, PartialEq)]
pub enum MetadataValue {
    Nil,
    Boolean(bool),
    Number(i64),
    Float(f64),
    BigInteger(BigInt),
    Character(char),
    Regex(String),
    Tagged(String, Box<MetadataValue>),
    String(String),
    Keyword(Keyword),
    Symbol(Symbol),
    Vector(Vec<MetadataValue>),
    List(Vec<MetadataValue>),
    Set(Vec<MetadataValue>),
    Map(Vec<(MetadataValue, MetadataValue)>),
}

#[derive(Debug, Clone, Default, PartialEq)]
pub struct Metadata {
    entries: Vec<(MetadataValue, MetadataValue)>,
}

impl Metadata {
    pub fn new(entries: Vec<(MetadataValue, MetadataValue)>) -> Rc<Self> {
        Rc::new(Self { entries })
    }

    pub fn document(value: impl Into<String>) -> Rc<Self> {
        Self::new(vec![(
            MetadataValue::Keyword(Keyword::from("doc")),
            MetadataValue::String(value.into()),
        )])
    }

    pub fn entries(&self) -> &[(MetadataValue, MetadataValue)] {
        &self.entries
    }

    pub fn get(&self, key: &MetadataValue) -> Option<&MetadataValue> {
        self.entries
            .iter()
            .rev()
            .find(|(candidate, _)| candidate == key)
            .map(|(_, value)| value)
    }

    pub fn get_keyword(&self, key: &str) -> Option<&MetadataValue> {
        self.get(&MetadataValue::Keyword(Keyword::from(key)))
    }

    pub fn flag(&self, key: &str) -> bool {
        matches!(self.get_keyword(key), Some(MetadataValue::Boolean(true)))
    }

    pub fn doc(&self) -> Option<&str> {
        match self.get_keyword("doc") {
            Some(MetadataValue::String(value)) => Some(value),
            _ => None,
        }
    }
}