Skip to main content

IpcResponse

Struct IpcResponse 

Source
pub struct IpcResponse {
    pub request_id: String,
    pub ok: bool,
    pub result: Option<IpcResult>,
    pub error: Option<DashboardError>,
}
Expand description

IPC response sent by the target process.

Fields§

§request_id: String

Request identifier copied from the request.

§ok: bool

Whether the request succeeded.

§result: Option<IpcResult>

Optional successful result.

§error: Option<DashboardError>

Optional structured error.

Implementations§

Source§

impl IpcResponse

Source

pub fn ok(request_id: impl Into<String>, result: IpcResult) -> Self

Creates a successful IPC response.

§Arguments
  • request_id: Request identifier copied from the request.
  • result: Successful result payload.
§Returns

Returns an IpcResponse with ok=true.

Examples found in repository?
examples/demo/bootstrap.rs (line 325)
321    async fn handle_request(&self, request: IpcRequest) -> IpcResponse {
322        // Dispatch the request.
323        match self.dispatch(&request).await {
324            // Return success response.
325            Ok(result) => IpcResponse::ok(request.request_id, result),
326            // Return error response.
327            Err(error) => IpcResponse::error(request.request_id, error),
328            // End dispatch match.
329        }
330        // End request handling.
331    }
Source

pub fn error(request_id: impl Into<String>, error: DashboardError) -> Self

Creates an error IPC response.

§Arguments
  • request_id: Request identifier copied from the request.
  • error: Structured error payload.
§Returns

Returns an IpcResponse with ok=false.

Examples found in repository?
examples/demo/bootstrap.rs (line 327)
321    async fn handle_request(&self, request: IpcRequest) -> IpcResponse {
322        // Dispatch the request.
323        match self.dispatch(&request).await {
324            // Return success response.
325            Ok(result) => IpcResponse::ok(request.request_id, result),
326            // Return error response.
327            Err(error) => IpcResponse::error(request.request_id, error),
328            // End dispatch match.
329        }
330        // End request handling.
331    }
332
333    /// Dispatches one request by method.
334    ///
335    /// # Arguments
336    ///
337    /// - `request`: Parsed IPC request.
338    ///
339    /// # Returns
340    ///
341    /// Returns a typed IPC result.
342    async fn dispatch(&self, request: &IpcRequest) -> Result<IpcResult, DashboardError> {
343        // Parse the request method.
344        let method = IpcMethod::parse(&request.method)?;
345        // Dispatch by method.
346        match method {
347            // Return protocol hello response.
348            IpcMethod::Hello => Ok(IpcResult::Hello {
349                // Include protocol version.
350                protocol_version: DASHBOARD_IPC_PROTOCOL_VERSION.to_owned(),
351                // Include registration payload.
352                registration: build_registration_payload(&self.config)?,
353                // End hello payload.
354            }),
355            // Return the current demo state.
356            IpcMethod::CurrentState => {
357                // Build current scenario state.
358                let state = self.scenario.state();
359                // Return state payload.
360                Ok(IpcResult::State {
361                    // Include target identifier.
362                    target_id: state.target.target_id.clone(),
363                    // Include boxed dashboard state.
364                    state: Box::new(state),
365                    // End state payload.
366                })
367                // End current state branch.
368            }
369            // Accept event subscription.
370            IpcMethod::EventsSubscribe => Ok(self.subscription("events")),
371            // Accept log subscription.
372            IpcMethod::LogsTail => Ok(self.subscription("logs")),
373            // Dispatch control command methods.
374            IpcMethod::CommandRestartChild
375            // Continue the demo expression.
376            | IpcMethod::CommandPauseChild
377            // Continue the demo expression.
378            | IpcMethod::CommandResumeChild
379            // Continue the demo expression.
380            | IpcMethod::CommandQuarantineChild
381            // Continue the demo expression.
382            | IpcMethod::CommandRemoveChild
383            // Continue the demo expression.
384            | IpcMethod::CommandAddChild
385            // Continue the demo expression.
386            | IpcMethod::CommandShutdownTree => self.command_result(request),
387            // End method match.
388        }
389        // End dispatch.
390    }
391
392    /// Builds one subscription response.
393    ///
394    /// # Arguments
395    ///
396    /// - `subscription`: Subscription kind.
397    ///
398    /// # Returns
399    ///
400    /// Returns a subscription result.
401    fn subscription(&self, subscription: &str) -> IpcResult {
402        // Build the subscription payload.
403        IpcResult::Subscription {
404            // Include target identifier.
405            target_id: self.scenario.target_id().to_owned(),
406            // Include subscription kind.
407            subscription: subscription.to_owned(),
408            // End subscription payload.
409        }
410        // End subscription construction.
411    }
412
413    /// Handles one command request.
414    ///
415    /// # Arguments
416    ///
417    /// - `request`: IPC request.
418    ///
419    /// # Returns
420    ///
421    /// Returns a command result IPC payload.
422    fn command_result(&self, request: &IpcRequest) -> Result<IpcResult, DashboardError> {
423        // Decode command parameters.
424        let command = decode_command_params(request)?;
425        // Apply the command to the scenario.
426        let result = self.scenario.command_result(command)?;
427        // Return command result payload.
428        Ok(IpcResult::CommandResult {
429            // Include target identifier.
430            target_id: self.scenario.target_id().to_owned(),
431            // Include command result.
432            result,
433            // End command result payload.
434        })
435        // End command result handling.
436    }
437    // Continue the demo expression.
438}
439
440/// Accepts demo IPC connections until the task is aborted.
441///
442/// # Arguments
443///
444/// - `listener`: Bound Unix listener.
445/// - `service`: Shared demo service.
446/// - `target_id`: Target process identifier.
447///
448/// # Returns
449///
450/// This async task has no returned value.
451async fn run_accept_loop(listener: UnixListener, service: Arc<DemoIpcService>, target_id: String) {
452    // Track connection tasks.
453    let mut connections = JoinSet::new();
454    // Accept connections until listener failure.
455    loop {
456        // Wait for either a new connection or a completed task.
457        tokio::select! {
458            // Accept one socket connection.
459            accepted = listener.accept() => {
460                // Handle accept result.
461                match accepted {
462                    // Spawn a connection task.
463                    Ok((stream, _)) => {
464                        // Clone the shared service.
465                        let service = Arc::clone(&service);
466                        // Clone the target identifier.
467                        let target_id = target_id.clone();
468                        // Spawn the per-connection task.
469                        connections.spawn(async move {
470                            // Handle the socket connection.
471                            handle_connection(stream, service, target_id).await
472                            // End connection task.
473                        });
474                    // Continue the demo expression.
475                    }
476                    // Stop when accept fails.
477                    Err(error) => {
478                        // Print accept failure.
479                        eprintln!("demo IPC accept loop stopped: {error}");
480                        // Leave the accept loop.
481                        break;
482                    // Continue the demo expression.
483                    }
484                    // End accept match.
485                }
486            // Continue the demo expression.
487            }
488            // Collect completed connection tasks.
489            Some(joined) = connections.join_next() => {
490                // Report task failures.
491                if let Err(error) = joined {
492                    // Print task failure.
493                    eprintln!("demo IPC connection task failed: {error}");
494                    // End task error branch.
495                }
496            // Continue the demo expression.
497            }
498        // Continue the demo expression.
499        }
500        // Continue accept loop.
501    }
502    // End accept loop.
503}
504
505/// Handles one newline-delimited JSON IPC connection.
506///
507/// # Arguments
508///
509/// - `stream`: Accepted Unix socket.
510/// - `service`: Shared demo service.
511/// - `target_id`: Target process identifier.
512///
513/// # Returns
514///
515/// Returns success when the socket closes cleanly.
516async fn handle_connection(
517    // Continue the demo expression.
518    stream: UnixStream,
519    // Continue the demo expression.
520    service: Arc<DemoIpcService>,
521    // Continue the demo expression.
522    target_id: String,
523    // Continue the demo expression.
524) -> Result<(), DashboardError> {
525    // Wrap the stream in a line reader.
526    let mut reader = BufReader::new(stream);
527    // Read requests until EOF.
528    loop {
529        // Allocate the request line.
530        let mut line = String::new();
531        // Read one newline-delimited request.
532        let bytes = reader.read_line(&mut line).await.map_err(|error| {
533            // Build read error.
534            io_error(
535                // Continue the demo expression.
536                "ipc_read_failed",
537                // Continue the demo expression.
538                "ipc_read",
539                // Continue the demo expression.
540                Some(target_id.clone()),
541                // Continue the demo expression.
542                error,
543                // Continue the demo expression.
544            )
545            // End read error construction.
546        })?;
547        // Stop when the peer closes the socket.
548        if bytes == 0 {
549            // Return clean close.
550            return Ok(());
551            // End EOF branch.
552        }
553        // Convert the request line into a response.
554        let response = response_for_line(&service, line.trim_end()).await;
555        // Write the response to the socket.
556        write_response(&mut reader, &response, &target_id).await?;
557        // Continue reading requests.
558    }
559    // End connection handling.
560}
561
562/// Converts one request line into a response.
563///
564/// # Arguments
565///
566/// - `service`: Demo IPC service.
567/// - `line`: One request line.
568///
569/// # Returns
570///
571/// Returns an IPC response.
572async fn response_for_line(service: &DemoIpcService, line: &str) -> IpcResponse {
573    // Parse the line.
574    match parse_request_line(line) {
575        // Dispatch parsed requests.
576        Ok(request) => service.handle_request(request).await,
577        // Return protocol errors.
578        Err(error) => IpcResponse::error("invalid-request", error),
579        // End parse match.
580    }
581    // End response conversion.
582}

Trait Implementations§

Source§

impl Clone for IpcResponse

Source§

fn clone(&self) -> IpcResponse

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for IpcResponse

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for IpcResponse

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for IpcResponse

Source§

fn eq(&self, other: &IpcResponse) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for IpcResponse

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for IpcResponse

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Paint for T
where T: ?Sized,

Source§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
Source§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
Source§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
Source§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
Source§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
Source§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
Source§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
Source§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
Source§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
Source§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
Source§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
Source§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
Source§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
Source§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
Source§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
Source§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
Source§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
Source§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
Source§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
Source§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
Source§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
Source§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
Source§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
Source§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
Source§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
Source§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
Source§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
Source§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
Source§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
Source§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
Source§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
Source§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
Source§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
Source§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
Source§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
Source§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
Source§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
Source§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
Source§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
Source§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
Source§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling Attribute value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
Source§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
Source§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
Source§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
Source§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
Source§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
Source§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
Source§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
Source§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi Quirk value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
Source§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
Source§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
Source§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
Source§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1:

renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
Source§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
Source§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
Source§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
Source§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the Condition value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
Source§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new Painted with a default Style. Read more
Source§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,