cocoanut 0.1.1

A Rust wrapper for Cocoa to develop macOS-specific GUI applications
# Cocoanut Refactoring Guide

## Overview

This document describes the refactoring effort to make Cocoanut more modular, trait-based, test-friendly, and capability-facing.

## Key Principles

### 1. **Trait-Based Design**
- Components implement capability traits (`Drawable`, `Textual`, `Positionable`)
- Enables composition and flexible component combinations
- Makes testing easier through trait mocking

### 2. **Capability-Facing**
- Components expose capabilities, not implementation details
- Users think in terms of "what can this do?" not "what type is this?"
- Traits define capabilities clearly

### 3. **Concise Code**
- Macros reduce boilerplate (e.g., `ns_string!`)
- Shared base structures (`ControlBase`)
- DRY principle throughout

### 4. **Test-Friendly**
- Traits enable easy mocking
- `test-mock` feature for testing without macOS
- Builder patterns for test setup

### 5. **Modular Organization**
- Clear separation of concerns
- Foundation traits in `traits.rs`
- Specific implementations in feature modules

## Module Organization

```
src/
├── error.rs              # Error types
├── utils.rs              # Utilities
├── traits.rs             # Foundation traits (NEW)
├── window.rs             # Window management
├── controls.rs           # Original controls (legacy)
├── controls_v2.rs        # Refactored controls (NEW)
├── menu.rs               # Menu system
├── layout.rs             # Layout system
├── styling.rs            # Styling system
├── events.rs             # Event handling
├── builder.rs            # Builder patterns
└── simple_app.rs         # High-level API
```

## Trait System

### Core Traits

#### `Drawable`
```rust
pub trait Drawable {
    fn as_view(&self) -> *mut Object;
    fn set_visible(&self, visible: bool) -> Result<()>;
    fn is_visible(&self) -> bool;
}
```
- All GUI components implement this
- Enables adding components to windows
- Provides visibility control

#### `Textual`
```rust
pub trait Textual {
    fn text(&self) -> &str;
    fn set_text(&mut self, text: &str) -> Result<()>;
}
```
- For components with text content
- Button, Label, TextField implement this
- Enables text manipulation

#### `Positionable`
```rust
pub trait Positionable {
    fn set_frame(&self, x: f64, y: f64, width: f64, height: f64) -> Result<()>;
    fn frame(&self) -> (f64, f64, f64, f64);
}
```
- For components with position/size
- Enables layout system integration
- Provides frame management

#### `Clickable`
```rust
pub trait Clickable {
    fn on_click<F>(&mut self, handler: F) -> Result<()>
    where F: Fn() + 'static;
}
```
- For interactive components
- Enables event binding
- Type-safe callbacks

#### `Container`
```rust
pub trait Container: Drawable {
    fn add_subview(&self, subview: *mut Object) -> Result<()>;
    fn remove_subview(&self, subview: *mut Object) -> Result<()>;
    fn subviews(&self) -> Vec<*mut Object>;
}
```
- For container views
- Enables composition
- Manages child views

## Code Patterns

### Macro for NSString Creation
```rust
macro_rules! ns_string {
    ($text:expr) => {{
        let cstr = CString::new($text)?;
        let ns_string_class = objc::class!(NSString);
        let ns_str: *mut Object = msg_send![ns_string_class, stringWithUTF8String: cstr.as_ptr()];
        ns_str
    }};
}
```
- Reduces boilerplate significantly
- Centralizes NSString creation
- Consistent error handling

### Base Structure Pattern
```rust
struct ControlBase {
    ns_view: *mut Object,
    id: String,
}
```
- Shared functionality for all controls
- Implements common traits
- Reduces code duplication

### Builder Pattern
```rust
pub struct ButtonBuilder {
    title: String,
    width: Option<f64>,
    height: Option<f64>,
}

impl ButtonBuilder {
    pub fn title(mut self, title: &str) -> Self { ... }
    pub fn size(mut self, width: f64, height: f64) -> Self { ... }
    pub fn build(self) -> Result<Button> { ... }
}
```
- Fluent API
- Type-safe configuration
- Easy to test

## Migration Guide

### From controls.rs to controls_v2.rs

**Old Way:**
```rust
let button = Button::new("Click")?;
button.set_title("New")?;
button.set_size(100.0, 50.0)?;
window.add_subview(button.ns_button())?;
```

**New Way:**
```rust
let button = Button::builder()
    .title("New")
    .size(100.0, 50.0)
    .build()?;
window.add_subview(button.as_view())?;
```

### Using Traits

**Old Way:**
```rust
// No trait support, type-specific methods
let title = button.title();
```

**New Way:**
```rust
// Trait-based, generic over capabilities
fn set_text<T: Textual>(component: &mut T, text: &str) -> Result<()> {
    component.set_text(text)
}
```

## Testing Strategy

### Unit Tests
```rust
#[test]
fn test_button_builder() {
    let builder = ButtonBuilder::default()
        .title("Test")
        .size(100.0, 50.0);
    assert_eq!(builder.title, "Test");
}
```

### Trait Tests
```rust
#[test]
fn test_drawable_trait_exists() {
    fn assert_drawable<T: Drawable>() {}
    // Compile-time verification
}
```

### Mock Testing
```rust
#[cfg(feature = "test-mock")]
// Components work without macOS
let button = Button::new("Test")?;
```

## Benefits

### For Users
- Cleaner, more intuitive API
- Less boilerplate code
- Better error messages
- Easier to learn

### For Developers
- Easier to add new components
- Trait-based composition
- Better code organization
- Easier to test

### For Maintainers
- Reduced code duplication
- Clear separation of concerns
- Easier to refactor
- Better documentation

## Next Steps

1. **Migrate controls.rs** - Gradually replace with controls_v2.rs
2. **Add more traits** - Stateful, Validatable, etc.
3. **Implement trait for all components** - Button, Label, TextField, etc.
4. **Create trait documentation** - Usage examples and patterns
5. **Add comprehensive tests** - Unit, integration, and property tests

## Performance Considerations

- **Zero-cost abstractions** - Traits compile to same code as direct calls
- **No runtime overhead** - All trait methods are inlined
- **Memory efficient** - ControlBase reduces duplication
- **Fast compilation** - Modular structure enables incremental builds

## Backward Compatibility

- `controls.rs` remains unchanged
- `controls_v2.rs` is new, opt-in
- Gradual migration path
- No breaking changes to public API