inspect-core 0.1.0

Core types and traits for the inspect-rs introspection system
Documentation
//! Path navigation for inspected values.

#[cfg(not(feature = "std"))]
use alloc::{string::String, vec::Vec};

/// A segment in an inspection path.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum PathSegment {
    /// A named field access (e.g., `.name`).
    Field(String),

    /// An indexed access (e.g., `[0]`).
    Index(usize),
}

/// A path through an inspected value tree.
///
/// Paths represent navigation from a root value to a specific nested value,
/// using field names and indices.
///
/// # Examples
///
/// ```
/// use inspect_core::{InspectPath, PathSegment};
///
/// let path = InspectPath::new()
///     .field("users")
///     .index(2)
///     .field("name");
///
/// assert_eq!(path.to_string(), "users[2].name");
/// ```
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct InspectPath {
    segments: Vec<PathSegment>,
}

impl InspectPath {
    /// Create a new empty path.
    pub fn new() -> Self {
        Self { segments: Vec::new() }
    }

    /// Append a field access to this path.
    pub fn field(mut self, name: impl Into<String>) -> Self {
        self.segments.push(PathSegment::Field(name.into()));
        self
    }

    /// Append an index access to this path.
    pub fn index(mut self, idx: usize) -> Self {
        self.segments.push(PathSegment::Index(idx));
        self
    }

    /// Get the segments in this path.
    pub fn segments(&self) -> &[PathSegment] {
        &self.segments
    }

    /// Check if this path is empty (refers to root).
    pub fn is_empty(&self) -> bool {
        self.segments.is_empty()
    }

    /// Get the length of this path.
    pub fn len(&self) -> usize {
        self.segments.len()
    }
}

impl core::fmt::Display for InspectPath {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        for (i, segment) in self.segments.iter().enumerate() {
            match segment {
                PathSegment::Field(name) => {
                    if i > 0 {
                        write!(f, ".")?;
                    }
                    write!(f, "{}", name)?;
                }
                PathSegment::Index(idx) => {
                    write!(f, "[{}]", idx)?;
                }
            }
        }
        Ok(())
    }
}