# Wasot Selector Implementation Report

## Overview

This report documents the implementation of CSS-inspired selectors for the Wasot markup language. The selector system enables querying and filtering Wasot documents based on element types and relationships, similar to how CSS selectors work with HTML.

## Implementation Summary

### Architecture

The selector implementation follows Wasot's event-driven architecture:

1. **Parser** - Uses the Pest parser generator to parse selector strings into an AST
2. **AST** - Represents selectors as typed Rust structures for easy manipulation
3. **Consumer** - Implements the `Consumer` trait to match selectors against the event stream
4. **CLI Integration** - New `select` subcommand for command-line usage

### Key Components

#### 1. Selector AST (`src/selectors/ast.rs`)

The AST represents selectors using the following types:

```rust
pub enum Selector {
    Simple(SimpleSelector),
    Compound(CompoundSelector),
    Group(Vec<Selector>),
}

pub struct SimpleSelector {
    pub type_selector: Option<String>,
    // Additional selector types (class, id, etc.) can be added here
}

pub struct CompoundSelector {
    pub simple: SimpleSelector,
    pub combinator: Option<(Combinator, Box<CompoundSelector>)>,
}

pub enum Combinator {
    Descendant,  // space
    // Additional combinators (>, +, ~) can be added here
}
```

#### 2. Pest Grammar (`src/selectors/selectors.pest`)

The grammar supports type selectors and descendant combinators:

```pest
selector = { SOI ~ compound_selector ~ EOI }

compound_selector = {
    simple_selector ~ (combinator_part)*
}

combinator_part = {
    descendant_combinator ~ simple_selector
}

simple_selector = {
    type_selector
}

type_selector = @{
    identifier
}

descendant_combinator = { WHITESPACE+ }

identifier = @{
    (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_" | "-")*
}
```

#### 3. Selector Consumer (`src/consumers/selector_consumer.rs`)

The consumer maintains state to track the document structure:

- **Block Stack**: Tracks the current path through the document hierarchy
- **Pending Blocks**: Stores matched blocks until they're complete
- **Matching Logic**: Implements descendant combinator matching using path traversal

Key features:
- Streaming processing compatible with Wasot's event system
- Efficient state tracking using a stack
- Output abstraction for flexible result handling

### Implementation Approach

1. **Test-Driven Development**: All components were developed test-first
2. **Incremental Implementation**: Started with the most useful subset (type selectors + descendant combinator)
3. **Event-Stream Compatible**: Designed to work with Wasot's streaming architecture
4. **Extensible Design**: Easy to add new selector types and combinators

## Technical Challenges and Solutions

### 1. Streaming vs Tree-Based Matching

**Challenge**: CSS selectors typically operate on a complete DOM tree, but Wasot uses a streaming event model.

**Solution**: Implemented a state-tracking system using a block stack that maintains the current path through the document, enabling descendant matching without requiring the full tree in memory.

### 2. Thread Safety

**Challenge**: The `Consumer` trait requires thread-safe implementations for use with the bus channel system.

**Solution**: Designed an `OutputHandler` trait with `Arc<Mutex<W>>` for thread-safe writing, avoiding the need for the entire consumer to be `Send`.

### 3. Descendant Combinator Semantics

**Challenge**: Implementing proper CSS descendant matching where "A B" means B is a descendant of A at any depth.

**Solution**: Recursive path matching that checks if the right-hand selector matches the current element and the left-hand selector matches any ancestor in the path.

## Testing Strategy

1. **Unit Tests**: Each component (parser, AST, consumer) has comprehensive unit tests
2. **Integration Tests**: End-to-end tests using example Wasot files
3. **CLI Testing**: Manual testing with various selector patterns

Example test cases:
- Simple type selectors: `"paragraph"`, `"document"`
- Compound selectors: `"document section"`, `"section paragraph"`
- Nested structures: Testing proper parent-child relationships

## Performance Considerations

1. **Memory Efficiency**: The consumer only maintains a stack of active blocks, not the entire document
2. **Streaming Processing**: Compatible with Wasot's line-by-line parsing approach
3. **Lazy Evaluation**: Selectors are only evaluated when blocks complete

## Future Enhancements

Based on the implementation plan in `docs/selector_parser_notes.md`, the following selector types can be added incrementally:

1. **Argument selectors**: `[key=value]`, `[key]`
2. **Child combinator**: `parent > child`
3. **Class selectors**: `.class-name`
4. **ID selectors**: `#id`
5. **Pseudo-selectors**: `:first-child`, `:last-child`, `:nth-child(n)`
6. **Universal selector**: `*`
7. **Sibling combinators**: `+` (adjacent), `~` (general)
8. **Negation**: `:not(selector)`

## Usage Examples

### CLI Usage

```bash
# Select all paragraphs
cargo run -- select examples/selector-demo.wasot -s "paragraph"

# Select paragraphs within sections
cargo run -- select examples/selector-demo.wasot -s "section paragraph"

# Multiple selectors
cargo run -- select examples/selector-demo.wasot -s "document" -s "section" -s "paragraph"
```

### Example Output

For the selector `"section paragraph"` on a document with nested structure:

```
Matched: section paragraph
  First paragraph in section
  With multiple lines
---
Matched: section paragraph
  Another paragraph in the same section
---
```

## Integration with Wasot Architecture

The selector implementation integrates seamlessly with Wasot's existing architecture:

1. **Event System**: Uses standard `WasotEvent` types
2. **Consumer Pattern**: Implements the `Consumer` trait
3. **CLI Framework**: Extends the existing clap-based CLI
4. **Error Handling**: Uses Wasot's standard error types

## Conclusion

The selector implementation provides a solid foundation for querying Wasot documents using familiar CSS-like syntax. The design is both efficient and extensible, allowing for incremental enhancement while maintaining compatibility with Wasot's streaming architecture.

The implementation demonstrates how Wasot's event-driven design can support complex document querying operations without sacrificing performance or memory efficiency.