Skip to main content

victauri_core/
lib.rs

1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3//! Core types and protocol for Victauri — full-stack introspection for Tauri apps via MCP.
4//!
5//! This crate provides the shared type system used by all Victauri crates.
6//! It has no Tauri dependency and can be used independently for testing.
7
8#[doc(hidden)]
9pub extern crate inventory;
10
11pub mod codegen;
12pub mod error;
13pub mod event;
14#[cfg(feature = "middleware")]
15pub mod middleware;
16pub mod recording;
17pub mod registry;
18pub mod security;
19pub mod snapshot;
20pub mod types;
21pub mod verification;
22
23pub use codegen::{CodegenOptions, CodegenStyle, generate_test, generate_test_default};
24pub use error::VictauriError;
25pub use event::{AppEvent, EventLog, InteractionKind, IpcCall, IpcResult};
26pub use recording::{EventRecorder, RecordedEvent, RecordedSession, StateCheckpoint};
27pub use registry::{
28    CommandArg, CommandInfo, CommandInfoFactory, CommandRegistry, ScoredCommand,
29    auto_discovered_commands,
30};
31pub use snapshot::{DomElement, DomSnapshot, WindowState};
32pub use types::{Divergence, DivergenceSeverity, MemoryDelta, RefHandle, VerificationResult};
33pub use verification::{
34    AssertionCondition, AssertionResult, GhostCommand, GhostCommandReport, GhostSource,
35    IpcIntegrityReport, SemanticAssertion, check_ipc_integrity, detect_ghost_commands,
36    evaluate_assertion, verify_state,
37};
38
39/// Acquire a mutex lock, recovering from poisoning with a warning.
40///
41/// Victauri's mutex-protected data is append-only logs and registries where
42/// stale data is preferable to crashing the testing framework.
43pub fn acquire_lock<'a, T>(
44    mutex: &'a std::sync::Mutex<T>,
45    context: &str,
46) -> std::sync::MutexGuard<'a, T> {
47    mutex.lock().unwrap_or_else(|poisoned| {
48        tracing::error!("{context}: mutex was poisoned, recovering");
49        poisoned.into_inner()
50    })
51}
52
53/// Acquire a read lock on an `RwLock`, recovering from poisoning.
54pub fn acquire_read<'a, T>(
55    lock: &'a std::sync::RwLock<T>,
56    context: &str,
57) -> std::sync::RwLockReadGuard<'a, T> {
58    lock.read().unwrap_or_else(|poisoned| {
59        tracing::error!("{context}: RwLock was poisoned, recovering with read guard");
60        poisoned.into_inner()
61    })
62}
63
64/// Acquire a write lock on an `RwLock`, recovering from poisoning.
65pub fn acquire_write<'a, T>(
66    lock: &'a std::sync::RwLock<T>,
67    context: &str,
68) -> std::sync::RwLockWriteGuard<'a, T> {
69    lock.write().unwrap_or_else(|poisoned| {
70        tracing::error!("{context}: RwLock was poisoned, recovering with write guard");
71        poisoned.into_inner()
72    })
73}