use crate::error::Error; pub mod lib_executor; #[cfg(any(test, feature = "test-utils"))] pub mod mock; /// Trait for executing jj operations /// /// All methods are async for native jj-lib compatibility. #[async_trait::async_trait(?Send)] pub trait JjExecutor: Send + Sync { /// Check if current directory is within a jj repository async fn is_repository(&self) -> Result; /// Set the description of the current change /// /// The revset parameter should resolve to a single commit (e.g., /// `"@"`, `"xs"`, bookmark name) async fn describe(&self, revset: &str, message: &str) -> Result<(), Error>; /// Get the current description of a specific revision async fn get_description(&self, revset: &str) -> Result; /// Create a new empty child revision parented on `revset`. /// /// Equivalent to `jj new ` async fn new_revision(&self, revset: &str) -> Result<(), Error>; } #[cfg(test)] mod tests { use super::*; /// Test that JjExecutor trait definition compiles /// /// This test verifies: /// - The trait is properly defined with async methods /// - The trait has correct Send + Sync bounds /// - The trait can be used as a type bound #[test] fn trait_definition_compiles() { // If this compiles, the trait definition is valid fn _accepts_executor(_executor: E) {} // Verify trait bounds compile fn _accepts_executor_ref(_executor: &E) {} fn _accepts_executor_box(_executor: Box) {} } /// Test that JjExecutor can be used with trait objects /// /// This verifies the trait is object-safe #[test] fn trait_is_object_safe() { // This compiles only if the trait is object-safe let _: Option> = None; let _: Option<&dyn JjExecutor> = None; } /// Test that JjExecutor requires Send + Sync bounds /// /// This verifies implementors must be thread-safe #[test] fn trait_requires_send_sync() { fn _assert_send() {} fn _assert_sync() {} // MockJjExecutor implements the trait, so it must satisfy Send + Sync _assert_send::(); _assert_sync::(); } /// Test that mock can implement JjExecutor trait /// /// This is a compile-time check that the mock properly implements the trait #[test] fn mock_implements_trait() { let mock = mock::MockJjExecutor::new(); // If this compiles, the mock implements the trait fn _accepts_executor(_e: impl JjExecutor) {} _accepts_executor(mock); } }