dynpatch_core/
lib.rs

1//! # dynpatch-core
2//!
3//! Runtime engine for safe live code reloading in Rust.
4//!
5//! This crate provides the core functionality for loading, validating, and activating
6//! patches at runtime, with strong safety guarantees and transactional semantics.
7
8pub mod loader;
9pub mod registry;
10pub mod validator;
11pub mod error;
12pub mod metrics;
13
14pub use error::{Error, Result};
15pub use loader::{PatchLoader, Library};
16pub use registry::{PatchRegistry, PatchInfo, PatchRecord};
17pub use validator::{Validator, ValidationConfig};
18
19use dynpatch_interface::Version;
20use tracing::{debug, info};
21
22/// Initialize the dynpatch runtime with default settings
23///
24/// This sets up the global registry with sensible defaults.
25/// For more control, use `RuntimeBuilder`.
26pub fn init() {
27    debug!("Initializing dynpatch runtime with defaults");
28    info!("dynpatch v{} initialized", env!("CARGO_PKG_VERSION"));
29    // Global registry is lazily initialized
30}
31
32/// Builder for configuring the dynpatch runtime
33///
34/// # Example
35///
36/// ```ignore
37/// use dynpatch::RuntimeBuilder;
38/// use dynpatch_interface::Version;
39///
40/// RuntimeBuilder::new()
41///     .interface_version(Version::new(1, 0, 0))
42///     .type_hash(0x1234567890abcdef)
43///     .init();
44/// ```
45pub struct RuntimeBuilder {
46    interface_version: Version,
47    type_hash: u64,
48}
49
50impl RuntimeBuilder {
51    pub fn new() -> Self {
52        Self {
53            interface_version: Version::new(0, 1, 0),
54            type_hash: 0,
55        }
56    }
57
58    /// Set the expected interface version
59    pub fn interface_version(mut self, version: Version) -> Self {
60        self.interface_version = version;
61        self
62    }
63
64    /// Set the expected type hash
65    pub fn type_hash(mut self, hash: u64) -> Self {
66        self.type_hash = hash;
67        self
68    }
69
70    /// Initialize the runtime with these settings
71    pub fn init(self) {
72        info!(
73            "dynpatch runtime initialized: interface v{}, type_hash {:x}",
74            self.interface_version, self.type_hash
75        );
76        // Note: In a full implementation, this would configure the global registry
77        // For now, the global registry uses defaults
78    }
79}
80
81impl Default for RuntimeBuilder {
82    fn default() -> Self {
83        Self::new()
84    }
85}
86
87/// Reload a patch from the specified path
88///
89/// This is a convenience function that uses the global patch registry.
90/// For more control, use `PatchRegistry::load` directly.
91pub fn reload(path: &str) -> Result<()> {
92    registry::global_registry().load(path)
93}
94
95/// Rollback to the previous patch
96pub fn rollback() -> Result<()> {
97    registry::global_registry().rollback()
98}
99
100/// Get information about the currently active patch
101pub fn active_patch_info() -> Option<PatchInfo> {
102    registry::global_registry().active_patch()
103}
104
105/// Get the history of all loaded patches
106pub fn history() -> Vec<PatchRecord> {
107    registry::global_registry().history()
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_init() {
116        init();
117        // Should not panic
118    }
119}