Skip to main content

mdvault_core/scripting/
vault_context.rs

1//! Vault context for Lua scripting.
2//!
3//! This module provides the `VaultContext` struct which holds references
4//! to all vault repositories needed for executing vault operations from Lua.
5
6use std::path::PathBuf;
7use std::sync::Arc;
8
9use crate::captures::CaptureRepository;
10use crate::config::types::ResolvedConfig;
11use crate::index::IndexDb;
12use crate::macros::MacroRepository;
13use crate::templates::repository::TemplateRepository;
14use crate::types::TypeRegistry;
15
16use super::selector::SelectorCallback;
17
18/// Information about the current note being processed.
19///
20/// This is set when validating or processing a specific note,
21/// allowing Lua hooks to access note metadata.
22#[derive(Clone, Debug)]
23pub struct CurrentNote {
24    /// Path to the note relative to vault root.
25    pub path: String,
26    /// Note type from frontmatter.
27    pub note_type: String,
28    /// Note title.
29    pub title: Option<String>,
30    /// Frontmatter as YAML value.
31    pub frontmatter: Option<serde_yaml::Value>,
32    /// Note content.
33    pub content: String,
34}
35
36/// Context for vault operations accessible from Lua hooks.
37///
38/// This struct holds Arc references to avoid cloning large repositories.
39/// It's designed to be passed to Lua bindings for template/capture/macro execution.
40#[derive(Clone)]
41pub struct VaultContext {
42    /// Resolved configuration with paths.
43    pub config: Arc<ResolvedConfig>,
44    /// Template repository for loading templates.
45    pub template_repo: Arc<TemplateRepository>,
46    /// Capture repository for loading captures.
47    pub capture_repo: Arc<CaptureRepository>,
48    /// Macro repository for loading macros.
49    pub macro_repo: Arc<MacroRepository>,
50    /// Type registry for type definitions.
51    pub type_registry: Arc<TypeRegistry>,
52    /// Optional index database for query operations.
53    pub index_db: Option<Arc<IndexDb>>,
54    /// Optional current note being processed.
55    pub current_note: Option<CurrentNote>,
56    /// Vault root path for resolving relative paths.
57    pub vault_root: PathBuf,
58    /// Optional selector callback for interactive prompts.
59    pub selector_callback: Option<SelectorCallback>,
60}
61
62impl VaultContext {
63    /// Create a new VaultContext from owned values.
64    pub fn new(
65        config: ResolvedConfig,
66        template_repo: TemplateRepository,
67        capture_repo: CaptureRepository,
68        macro_repo: MacroRepository,
69        type_registry: TypeRegistry,
70    ) -> Self {
71        let vault_root = config.vault_root.clone();
72        Self {
73            config: Arc::new(config),
74            template_repo: Arc::new(template_repo),
75            capture_repo: Arc::new(capture_repo),
76            macro_repo: Arc::new(macro_repo),
77            type_registry: Arc::new(type_registry),
78            index_db: None,
79            current_note: None,
80            vault_root,
81            selector_callback: None,
82        }
83    }
84
85    /// Create a new VaultContext from Arc references.
86    pub fn from_arcs(
87        config: Arc<ResolvedConfig>,
88        template_repo: Arc<TemplateRepository>,
89        capture_repo: Arc<CaptureRepository>,
90        macro_repo: Arc<MacroRepository>,
91        type_registry: Arc<TypeRegistry>,
92    ) -> Self {
93        let vault_root = config.vault_root.clone();
94        Self {
95            config,
96            template_repo,
97            capture_repo,
98            macro_repo,
99            type_registry,
100            index_db: None,
101            current_note: None,
102            vault_root,
103            selector_callback: None,
104        }
105    }
106
107    /// Set the index database for query operations.
108    pub fn with_index(mut self, index_db: Arc<IndexDb>) -> Self {
109        self.index_db = Some(index_db);
110        self
111    }
112
113    /// Set the current note being processed.
114    pub fn with_current_note(mut self, note: CurrentNote) -> Self {
115        self.current_note = Some(note);
116        self
117    }
118
119    /// Set the selector callback for interactive prompts.
120    ///
121    /// The selector callback is called when Lua scripts invoke `mdv.selector()`.
122    /// It should display the items to the user and return the selected value.
123    pub fn with_selector(mut self, callback: SelectorCallback) -> Self {
124        self.selector_callback = Some(callback);
125        self
126    }
127}