//! This module contains the [`Module`] type and associated types. Each compilation unit //! (file) is represented by a module which is used to namespace "function" calls and //! accesses to global variables. //! //! They have unique identifiers in the form of UUIDs. use std::path::{Path, PathBuf}; use uuid::Uuid; use crate::model::module_registry::ModuleRegistry; /// The ID for a module. A tuple struct for type safety. #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] pub struct ModuleId(Uuid); impl ModuleId { pub fn from_module(module: Module) -> Self { module.id } /// Convenience method to get the [`Module`] from a [`ModuleId`]. pub fn to_module<'m>(&self, registry: &'m ModuleRegistry) -> Option<&'m Module> { registry.get(self) } /// Convenience method to get the [`Module`] name from a [`ModuleId`]. pub fn to_module_name<'m>(self, registry: &'m ModuleRegistry) -> Option<&'m str> { if let Some(module) = self.to_module(®istry) { Some(module.name.as_str()) } else { None } } } impl std::fmt::Display for ModuleId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } /// A single source file or compilation unit. Stores its own symbol table. #[derive(Debug)] pub struct Module { /// The name of the module. This is typically the name of the file, less the `.dsa` /// extension. pub name: String, /// The file path to the module. This is an absolute path. pub path: PathBuf, /// A unique ID for this module. pub id: ModuleId, } impl std::hash::Hash for Module { fn hash(&self, state: &mut H) { self.id.0.hash(state); } } impl Module { pub fn new>(name: String, path: P) -> Self { Self { name, path: path.as_ref().to_path_buf(), id: ModuleId(Uuid::new_v4()), } } }