wrap method

void wrap(
  1. LogSpan wrapper(
    1. LogSpan child
    )
)

Wraps this span with a wrapper span.

The wrapper function receives this span and should return a new span that contains this span as a child.

Note: The wrapper function will receive this span as an argument. When adding this span as a child to the wrapper (e.g., via constructor parameter or addChild), the span will be automatically removed from its current parent. The wrap method handles updating the original parent to point to the wrapper.

Example:

span.wrap((child) => AnsiStyled(foreground: Ansi16.red, child: child));

Implementation

void wrap(LogSpan Function(LogSpan child) wrapper) {
  final originalParent = _parent;
  // Store position info before the wrapper constructor potentially removes us
  int? originalIndex;
  String? originalSlotKey;
  if (originalParent is MultiChildSpan) {
    originalIndex = originalParent._children.indexOf(this);
  } else if (originalParent is SlottedSpan) {
    for (final entry in originalParent._slots.entries) {
      if (entry.value == this) {
        originalSlotKey = entry.key;
        break;
      }
    }
  }

  // Create the wrapper - this may remove this span from its original parent
  // when addChild or setting child property is called
  final wrapped = wrapper(this);

  // If we had an original parent, we need to put the wrapper in our place
  if (originalParent != null) {
    switch (originalParent) {
      case final SingleChildSpan parent:
        // Set the wrapper as the new child (we were already removed)
        if (parent._child == null || parent._child == this) {
          wrapped._parent?._removeChild(wrapped);
          wrapped._parent = parent;
          parent._child = wrapped;
        }
      case final MultiChildSpan parent:
        // Insert wrapper at our original position
        if (originalIndex != null && originalIndex >= 0) {
          wrapped._parent?._removeChild(wrapped);
          wrapped._parent = parent;
          // Clamp index in case list changed
          final insertIndex = originalIndex.clamp(0, parent._children.length);
          parent._children.insert(insertIndex, wrapped);
        }
      case final SlottedSpan parent:
        // Fill our original slot with the wrapper
        if (originalSlotKey != null) {
          wrapped._parent?._removeChild(wrapped);
          wrapped._parent = parent;
          parent._slots[originalSlotKey] = wrapped;
        }
    }
  }
}