ControlInterpreter

Struct ControlInterpreter 

Source
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: bool

Whether 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>

Source

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 authenticated 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 interpreter = ControlInterpreter::new(&mut controller);
Source

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);
Source

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"]);
Source

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
§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());

Auto Trait Implementations§

§

impl<'a> Freeze for ControlInterpreter<'a>

§

impl<'a> RefUnwindSafe for ControlInterpreter<'a>

§

impl<'a> Send for ControlInterpreter<'a>

§

impl<'a> Sync for ControlInterpreter<'a>

§

impl<'a> Unpin for ControlInterpreter<'a>

§

impl<'a> !UnwindSafe for ControlInterpreter<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.