Trait scpi::tree::command::Command

source ·
pub trait Command<D: Device> {
    // Provided methods
    fn meta(&self) -> CommandTypeMeta { ... }
    fn event(
        &self,
        _device: &mut D,
        _context: &mut Context<'_>,
        _params: Parameters<'_, '_>
    ) -> Result<()> { ... }
    fn query(
        &self,
        _device: &mut D,
        _context: &mut Context<'_>,
        _params: Parameters<'_, '_>,
        _resp: ResponseUnit<'_>
    ) -> Result<()> { ... }
}
Expand description

This trait implements a command with event/query operations.

Example

use scpi::{error::Result, tree::prelude::*, cmd_both};

struct MyCommand;
impl<D> Command<D> for MyCommand
where
    D: Device,// or MyDevice or Device + AdditionalTrait or ...
{
    // Create a stub for Command::meta()
    cmd_both!();

    // `HELLo:WORLd`
    fn event(&self, _device: &mut D, _context: &mut Context, _params: Parameters) -> Result<()> {
        //  Do stuff
        println!("Hello world");
        Ok(())
    }

    // `HELLo:WORLd?`
    fn query(
        &self,
        _device: &mut D,
        _context: &mut Context,
        _params: Parameters,
        mut response: ResponseUnit,
    ) -> Result<()> {
        response.data(&b"Hello world"[..]).finish()
    }
}

The default stubs for Command::event and Command::query returns an ErrorCode::UndefinedHeader error.

Naming convention

A command impl should be named in PascalCase after the shortform header mnemonics upp to the last which should be in longform. Common commands should be named as-is without ‘*’ obv.

Examples:

  • INITiate[:IMMediate][:ALL] => InitImmAllCommand
  • SYSTem:ERRor[:NEXT] => SystErrNextCommand
  • SENSe:VOLTage[:DC]:NPLCycles => SensVoltDcNPLCyclesCommand
  • *TRG => TrgCommand

Sometimes a command is re-used in multiple branches, in that case one might skip the changing branches in the name. Generics may be used to specialize the command.

  • SENSe(:VOLTage|:CURRent|..)([:DC]|:AC):RESolution => SensResolutionCommand or SensResolutionCommand<Func>

When instantaiting more than one command it is recommended to use a command constant/member or const generics, i.e. like this:

  • OUTPut[<n>]:ATTenuation => OutpAttenuationCommand<const N: usize = 1>
  • ARM:SEQuence[<n1>]:LAYer[<n2>][:IMMediate] => ArmSeqLayImmediateCommand { sequence: n1, layer: n2 }

All of these forms may also be combined for extra headache.

In the end readability overrules the above conventions if the name gets too verbose…

Provided Methods§

source

fn meta(&self) -> CommandTypeMeta

Hint about the allowed forms this command allows.

Not actually binding in any way but can be used to provide autocompletion and help info. Use cmd_nquery!, cmd_qonly!, or cmd_both! to automatically create the corresponding stub.

source

fn event( &self, _device: &mut D, _context: &mut Context<'_>, _params: Parameters<'_, '_> ) -> Result<()>

Called when the event form COMmand is used.

Default behaviour returns a ErrorCode::UndefinedHeader error.

source

fn query( &self, _device: &mut D, _context: &mut Context<'_>, _params: Parameters<'_, '_>, _resp: ResponseUnit<'_> ) -> Result<()>

Called when the query form COMmand? is used

Default behaviour returns a ErrorCode::UndefinedHeader error.

Implementors§

source§

impl<D> Command<D> for Todowhere D: Device,