From 6ab7760822ccd24b4ef126d4737d41f1be15fe19 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 1 Mar 2023 16:30:58 +0100 Subject: Split up `model` module --- src/eval/module.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/eval/module.rs (limited to 'src/eval/module.rs') diff --git a/src/eval/module.rs b/src/eval/module.rs new file mode 100644 index 00000000..e911d859 --- /dev/null +++ b/src/eval/module.rs @@ -0,0 +1,87 @@ +use std::fmt::{self, Debug, Formatter}; +use std::sync::Arc; + +use ecow::{eco_format, EcoString}; + +use super::{Content, Scope, Value}; +use crate::diag::StrResult; + +/// An evaluated module, ready for importing or typesetting. +#[derive(Clone, Hash)] +pub struct Module(Arc); + +/// The internal representation. +#[derive(Clone, Hash)] +struct Repr { + /// The module's name. + name: EcoString, + /// The top-level definitions that were bound in this module. + scope: Scope, + /// The module's layoutable contents. + content: Content, +} + +impl Module { + /// Create a new module. + pub fn new(name: impl Into) -> Self { + Self(Arc::new(Repr { + name: name.into(), + scope: Scope::new(), + content: Content::empty(), + })) + } + + /// Update the module's scope. + pub fn with_scope(mut self, scope: Scope) -> Self { + Arc::make_mut(&mut self.0).scope = scope; + self + } + + /// Update the module's content. + pub fn with_content(mut self, content: Content) -> Self { + Arc::make_mut(&mut self.0).content = content; + self + } + + /// Get the module's name. + pub fn name(&self) -> &EcoString { + &self.0.name + } + + /// Access the module's scope. + pub fn scope(&self) -> &Scope { + &self.0.scope + } + + /// Access the module's scope, mutably. + pub fn scope_mut(&mut self) -> &mut Scope { + &mut Arc::make_mut(&mut self.0).scope + } + + /// Try to access a definition in the module. + pub fn get(&self, name: &str) -> StrResult<&Value> { + self.scope().get(&name).ok_or_else(|| { + eco_format!("module `{}` does not contain `{name}`", self.name()) + }) + } + + /// Extract the module's content. + pub fn content(self) -> Content { + match Arc::try_unwrap(self.0) { + Ok(repr) => repr.content, + Err(arc) => arc.content.clone(), + } + } +} + +impl Debug for Module { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "", self.name()) + } +} + +impl PartialEq for Module { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} -- cgit v1.2.3