1
0
dust/dust-lang/src/context.rs

111 lines
3.0 KiB
Rust
Raw Normal View History

2024-02-25 18:49:26 +00:00
use std::{
collections::BTreeMap,
sync::{Arc, RwLock, RwLockReadGuard},
2024-02-25 18:49:26 +00:00
};
2024-03-06 23:15:25 +00:00
use crate::{
abstract_tree::{Identifier, Type},
2024-03-19 22:31:52 +00:00
error::{RwLockPoisonError, ValidationError},
2024-03-24 00:36:23 +00:00
Value,
2024-03-06 23:15:25 +00:00
};
2024-02-25 18:49:26 +00:00
2024-03-12 01:57:27 +00:00
#[derive(Clone, Debug)]
2024-03-17 17:36:31 +00:00
pub struct Context {
inner: Arc<RwLock<BTreeMap<Identifier, ValueData>>>,
2024-02-25 18:49:26 +00:00
}
impl Context {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(BTreeMap::new())),
}
}
2024-03-17 17:36:31 +00:00
pub fn with_data(data: BTreeMap<Identifier, ValueData>) -> Self {
2024-02-25 18:49:26 +00:00
Self {
2024-03-06 23:15:25 +00:00
inner: Arc::new(RwLock::new(data)),
}
}
2024-03-20 08:42:13 +00:00
pub fn inner(
&self,
) -> Result<RwLockReadGuard<BTreeMap<Identifier, ValueData>>, RwLockPoisonError> {
Ok(self.inner.read()?)
}
2024-03-17 17:36:31 +00:00
pub fn inherit_types_from(&self, other: &Context) -> Result<(), RwLockPoisonError> {
let mut self_data = self.inner.write()?;
2024-03-17 17:36:31 +00:00
for (identifier, value_data) in other.inner.read()?.iter() {
if let ValueData::Type(Type::Function { .. }) = value_data {
self_data.insert(identifier.clone(), value_data.clone());
}
}
2024-03-17 17:36:31 +00:00
Ok(())
}
2024-03-17 17:36:31 +00:00
pub fn inherit_data_from(&self, other: &Context) -> Result<(), RwLockPoisonError> {
let mut self_data = self.inner.write()?;
2024-03-17 17:36:31 +00:00
for (identifier, value_data) in other.inner.read()?.iter() {
self_data.insert(identifier.clone(), value_data.clone());
}
2024-03-17 17:36:31 +00:00
Ok(())
}
2024-03-17 17:36:31 +00:00
pub fn contains(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> {
2024-03-24 13:10:49 +00:00
Ok(self.inner.read()?.contains_key(identifier))
2024-03-12 01:57:27 +00:00
}
2024-03-19 22:31:52 +00:00
pub fn get_type(&self, identifier: &Identifier) -> Result<Option<Type>, ValidationError> {
2024-03-17 17:36:31 +00:00
if let Some(value_data) = self.inner.read()?.get(identifier) {
let r#type = match value_data {
2024-03-20 12:36:18 +00:00
ValueData::Type(r#type) => r#type.clone(),
2024-03-19 22:31:52 +00:00
ValueData::Value(value) => value.r#type(self)?,
2024-03-12 01:57:27 +00:00
};
2024-03-23 12:15:48 +00:00
Ok(Some(r#type.clone()))
} else {
Ok(None)
2024-03-18 12:15:30 +00:00
}
2024-03-06 23:15:25 +00:00
}
2024-03-17 17:36:31 +00:00
pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> {
if let Some(ValueData::Value(value)) = self.inner.read()?.get(identifier) {
Ok(Some(value.clone()))
2024-03-12 01:57:27 +00:00
} else {
2024-03-18 12:15:30 +00:00
Ok(None)
2024-02-25 18:49:26 +00:00
}
}
2024-03-06 23:15:25 +00:00
pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> {
self.inner
.write()?
2024-03-17 17:36:31 +00:00
.insert(identifier, ValueData::Type(r#type));
2024-02-25 18:49:26 +00:00
2024-03-06 23:15:25 +00:00
Ok(())
2024-02-25 18:49:26 +00:00
}
2024-03-06 23:15:25 +00:00
pub fn set_value(&self, identifier: Identifier, value: Value) -> Result<(), RwLockPoisonError> {
2024-03-24 13:10:49 +00:00
self.inner
.write()?
.insert(identifier, ValueData::Value(value));
2024-02-25 18:49:26 +00:00
Ok(())
}
2024-03-23 12:47:57 +00:00
pub fn remove(&self, identifier: &Identifier) -> Result<Option<ValueData>, RwLockPoisonError> {
let removed = self.inner.write()?.remove(identifier);
Ok(removed)
}
2024-02-25 18:49:26 +00:00
}
2024-03-17 17:36:31 +00:00
#[derive(Clone, Debug, PartialEq)]
pub enum ValueData {
Type(Type),
Value(Value),
}