shelly-shell 0.5.3

A Rust based Unix style shell with a typed and structured language syntax.

use std::{
    cell::RefCell,
    collections::HashSet,
    fmt::{self, Debug, Formatter},
    rc::Rc,
};

use crate::language::{
    bytecode::FunctionRef, data::value::Value, interpreter::CallFrame, text::location::Location,
};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FailureStatus
{
    Pending,
    Propagating,
    Acknowledged,
}

#[derive(Clone, Debug)]
pub struct RelatedFailure
{
    pub relation: String,
    pub snapshot: Value,
    pub origin: Location,
    pub native_origin: Option<Location>,
    pub frames: Vec<CallFrame>,
}

#[derive(Clone, Copy, Debug)]
pub enum ControlFailure
{
    Interrupted,
    CleanupAbort,
    CleanupTimeout,
}

#[derive(Clone)]
pub struct FailureOccurrence
{
    pub id: u64,
    pub owner: u64,
    pub control: Option<ControlFailure>,
    pub status: FailureStatus,
    pub origin: Location,
    pub native_origin: Option<Location>,
    pub frames: Vec<CallFrame>,
    pub propagation: Vec<Location>,
    pub related: Vec<RelatedFailure>,
    pub slots: HashSet<usize>,
    pub formatter: Option<FunctionRef>,
    pub rethrow_source: Option<u64>,
}

impl Debug for FailureOccurrence
{
    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result
    {
        formatter
            .debug_struct("FailureOccurrence")
            .field("id", &self.id)
            .field("status", &self.status)
            .finish()
    }
}

impl PartialEq for FailureOccurrence
{
    fn eq(&self, other: &Self) -> bool
    {
        self.id == other.id
    }
}

pub type FailureRef = Rc<RefCell<FailureOccurrence>>;

pub fn occurrence(value: &Value) -> Option<FailureRef>
{
    match value.underlying()
    {
        Value::Struct(item) => item.failure.clone(),
        _ => None,
    }
}

pub fn pending(value: &Value) -> Option<FailureRef>
{
    occurrence(value).filter(|item| item.borrow().status == FailureStatus::Pending)
}

pub fn marked(value: &Value) -> bool
{
    matches!(value.underlying(), Value::Struct(item) if item.definition.error)
}