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// Shared plumbing for the plugin/CLI crates — not part of the supported API.
15#[cfg(feature = "middleware")]
16#[doc(hidden)]
17pub mod middleware;
18pub mod recording;
19pub mod registry;
20#[doc(hidden)]
21pub mod security;
22pub mod snapshot;
23pub mod types;
24pub mod verification;
25
26pub use codegen::{CodegenOptions, CodegenStyle, generate_test, generate_test_default};
27pub use error::VictauriError;
28pub use event::{AppEvent, EventLog, InteractionKind, IpcCall, IpcResult};
29pub use recording::{EventRecorder, RecordedEvent, RecordedSession, StateCheckpoint};
30pub use registry::{
31    CommandArg, CommandInfo, CommandInfoFactory, CommandRegistry, ScoredCommand,
32    auto_discovered_commands,
33};
34pub use snapshot::{DomElement, DomSnapshot, WindowState};
35pub use types::{Divergence, DivergenceSeverity, MemoryDelta, RefHandle, VerificationResult};
36pub use verification::{
37    AssertionCondition, AssertionResult, GhostCommand, GhostCommandReport, GhostSource,
38    IpcIntegrityReport, SemanticAssertion, check_ipc_integrity, detect_ghost_commands,
39    evaluate_assertion, verify_state,
40};
41
42/// Acquire a mutex lock, recovering from poisoning with a warning.
43///
44/// Victauri's mutex-protected data is append-only logs and registries where
45/// stale data is preferable to crashing the testing framework.
46#[doc(hidden)]
47pub fn acquire_lock<'a, T>(
48    mutex: &'a std::sync::Mutex<T>,
49    context: &str,
50) -> std::sync::MutexGuard<'a, T> {
51    mutex.lock().unwrap_or_else(|poisoned| {
52        tracing::error!("{context}: mutex was poisoned, recovering");
53        poisoned.into_inner()
54    })
55}
56
57/// Acquire a read lock on an `RwLock`, recovering from poisoning.
58#[doc(hidden)]
59pub fn acquire_read<'a, T>(
60    lock: &'a std::sync::RwLock<T>,
61    context: &str,
62) -> std::sync::RwLockReadGuard<'a, T> {
63    lock.read().unwrap_or_else(|poisoned| {
64        tracing::error!("{context}: RwLock was poisoned, recovering with read guard");
65        poisoned.into_inner()
66    })
67}
68
69/// Acquire a write lock on an `RwLock`, recovering from poisoning.
70#[doc(hidden)]
71pub fn acquire_write<'a, T>(
72    lock: &'a std::sync::RwLock<T>,
73    context: &str,
74) -> std::sync::RwLockWriteGuard<'a, T> {
75    lock.write().unwrap_or_else(|poisoned| {
76        tracing::error!("{context}: RwLock was poisoned, recovering with write guard");
77        poisoned.into_inner()
78    })
79}
80
81/// Compiles the README's examples as doctests, so the crates.io landing page
82/// cannot drift from the API again (its `CommandInfo` struct literal outlived the
83/// 0.9 `#[non_exhaustive]` change).
84#[cfg(doctest)]
85#[doc = include_str!("../README.md")]
86pub struct ReadmeDoctests;