Skip to main content

ContextBuilder

Struct ContextBuilder 

Source
pub struct ContextBuilder { /* private fields */ }
Expand description

Fluent builder for constructing DualContextError.

§Purpose

Provides ergonomic API for building errors with:

  • Public/internal separation
  • Type-safe category assignment
  • Sensible defaults

§State Tracking

Builder tracks context assignment to prevent accidental overwrites:

  • Debug builds: Panics on double-set with clear diagnostics
  • Release builds: Last-write-wins (no runtime overhead)

This is intentional: debug builds catch logic bugs, release builds prioritize performance and allow intentional overwrites in complex error construction.

If you need compile-time enforcement, consider the typestate pattern, but this was rejected for ergonomics (see DESIGN_DECISIONS.md).

§Example

use palisade_errors::{ContextBuilder, OperationCategory, SocAccess};

let err = ContextBuilder::new()
    .public_lie("Access denied")
    .internal_sensitive("Unauthorized: user lacks 'admin' role")
    .category(OperationCategory::Detection)
    .build();

// Public message: "Access denied"
assert_eq!(err.external_message(), "Access denied");

// Internal context requires SocAccess
let access = SocAccess::acquire();
let internal = err.internal().expose_sensitive(&access);
assert_eq!(internal, Some("Unauthorized: user lacks 'admin' role"));

Implementations§

Source§

impl ContextBuilder

Source

pub fn new() -> Self

Create a new builder with default category (System).

Source

pub fn public_lie(self, message: impl Into<Cow<'static, str>>) -> Self

Set public context as deceptive lie (default for honeypot deployments).

§Panics (Debug Mode)

Panics if public context was already set. This prevents silent overwrites in complex error construction flows.

§Example
let builder = ContextBuilder::new()
    .public_lie("Permission denied");
Source

pub fn public_truth(self, message: impl Into<Cow<'static, str>>) -> Self

Set public context as truthful message (requires external_signaling feature).

§Panics (Debug Mode)

Panics if public context was already set.

§Example
let builder = ContextBuilder::new()
    .public_truth("Invalid JSON syntax");
Source

pub fn internal_diagnostic(self, message: impl Into<Cow<'static, str>>) -> Self

Set internal context as diagnostic (non-sensitive).

§Panics (Debug Mode)

Panics if internal context was already set.

§Example
let builder = ContextBuilder::new()
    .internal_diagnostic("Database query failed: timeout after 30s");
Source

pub fn internal_sensitive(self, message: impl Into<Cow<'static, str>>) -> Self

Set internal context as sensitive (requires SocAccess to view).

§Panics (Debug Mode)

Panics if internal context was already set.

§Example
let builder = ContextBuilder::new()
    .internal_sensitive("Failed to read /etc/shadow: permission denied");
Source

pub fn internal_lie(self, message: impl Into<Cow<'static, str>>) -> Self

Set internal context as tracked lie (for deception analysis).

§Panics (Debug Mode)

Panics if internal context was already set.

§Example
let builder = ContextBuilder::new()
    .internal_lie("Normal database operation completed successfully");
Source

pub fn category(self, category: OperationCategory) -> Self

Set operation category.

§Example
let builder = ContextBuilder::new()
    .category(OperationCategory::Detection);
Source

pub fn build(self) -> DualContextError

Build the final DualContextError.

§Panics

Panics if public or internal context is not set. Use try_build() for a non-panicking version.

§Example
let err = ContextBuilder::new()
    .public_lie("Operation failed")
    .internal_diagnostic("Timeout")
    .category(OperationCategory::IO)
    .build();
Source

pub fn try_build(self) -> Result<DualContextError, ContextBuilderError>

Try to build the DualContextError, returning an error if incomplete.

§Errors

Returns Err(ContextBuilderError) if public or internal context is missing. The error includes diagnostic information about builder state.

§Example
let result = ContextBuilder::new()
    .public_lie("Error")
    .try_build();

assert!(result.is_err()); // Missing internal context

Trait Implementations§

Source§

impl Default for ContextBuilder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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> 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, 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.