pub struct ControlInterpreter<'a> {
pub is_multiline_context: bool,
/* private fields */
}Expand description
Interactive command interpreter for Tor control protocol.
ControlInterpreter provides a high-level interface for interacting with
Tor, combining direct control protocol access with convenience commands
for common operations.
§Conceptual Role
The interpreter sits between user input and the Controller, providing:
- Command routing (interpreter vs. Tor commands)
- Event buffering and retrieval
- Relay lookup by various identifiers
- Help and documentation access
§Invariants
- The event buffer never exceeds [
MAX_EVENTS] entries - Events are stored in reverse chronological order (newest first)
- The underlying controller connection must remain valid
§Thread Safety
ControlInterpreter is Send but not Sync due to the mutable
reference to the underlying Controller.
§Example
use stem_rs::Controller;
use stem_rs::interpreter::ControlInterpreter;
let mut controller = Controller::from_port("127.0.0.1:9051".parse()?).await?;
controller.authenticate(None).await?;
let mut interpreter = ControlInterpreter::new(&mut controller);
// Query relay information
let info = interpreter.run_command("/info MyRelay").await?;
// Send a signal to Tor
let result = interpreter.run_command("SIGNAL NEWNYM").await?;Fields§
§is_multiline_context: boolWhether the interpreter is in a multiline input context.
This is set to true when the user is entering a multiline command
(such as LOADCONF or POSTDESCRIPTOR). The prompt should change
to indicate continuation (e.g., ... instead of >>> ).
Implementations§
Source§impl<'a> ControlInterpreter<'a>
impl<'a> ControlInterpreter<'a>
Sourcepub fn new(controller: &'a mut Controller) -> Self
pub fn new(controller: &'a mut Controller) -> Self
Creates a new interpreter wrapping the given controller.
The interpreter is initialized with:
- An empty event buffer
- Python command mode enabled
- Multiline context disabled
§Arguments
controller- A mutable reference to an authenticatedController
§Example
use stem_rs::Controller;
use stem_rs::interpreter::ControlInterpreter;
let mut controller = Controller::from_port("127.0.0.1:9051".parse()?).await?;
controller.authenticate(None).await?;
let interpreter = ControlInterpreter::new(&mut controller);Sourcepub fn add_event(&mut self, event: ParsedEvent)
pub fn add_event(&mut self, event: ParsedEvent)
Adds an event to the buffer.
Events are stored in reverse chronological order (newest first). If the buffer is full, the oldest event is discarded.
§Arguments
event- The parsed event to add
§Example
use stem_rs::Controller;
use stem_rs::interpreter::ControlInterpreter;
use stem_rs::events::ParsedEvent;
let mut interpreter = ControlInterpreter::new(&mut controller);
// Events would typically come from the controller's event stream
// interpreter.add_event(event);Sourcepub fn get_events(&self, event_types: &[&str]) -> Vec<&ParsedEvent>
pub fn get_events(&self, event_types: &[&str]) -> Vec<&ParsedEvent>
Retrieves buffered events, optionally filtered by type.
Returns events in reverse chronological order (newest first).
§Arguments
event_types- Event types to filter by (case-insensitive). If empty, all events are returned.
§Returns
A vector of references to matching events.
§Example
use stem_rs::Controller;
use stem_rs::interpreter::ControlInterpreter;
let interpreter = ControlInterpreter::new(&mut controller);
// Get all events
let all_events = interpreter.get_events(&[]);
// Get only bandwidth events
let bw_events = interpreter.get_events(&["BW"]);
// Get circuit and stream events
let circ_stream = interpreter.get_events(&["CIRC", "STREAM"]);Sourcepub async fn run_command(&mut self, command: &str) -> Result<String, Error>
pub async fn run_command(&mut self, command: &str) -> Result<String, Error>
Executes a command and returns the result.
Commands are routed based on their prefix:
- Commands starting with
/are interpreter commands - All other commands are sent to Tor’s control interface
§Arguments
command- The command string to execute
§Returns
The command output as a string, or an error.
§Errors
Error::SocketClosed- If/quitorQUITis executedError::Socket- If communication with Tor failsError::InvalidArguments- If relay lookup fails
§Example
use stem_rs::Controller;
use stem_rs::interpreter::ControlInterpreter;
let mut interpreter = ControlInterpreter::new(&mut controller);
// Interpreter command
let help = interpreter.run_command("/help").await?;
// Tor control command
let version = interpreter.run_command("GETINFO version").await?;
// Empty commands return empty string
let empty = interpreter.run_command("").await?;
assert!(empty.is_empty());