cocoanut 0.1.1

A Rust wrapper for Cocoa to develop macOS-specific GUI applications
# Module Standardization Guide

## Overview

This document describes the standardized module structure for Cocoanut to ensure consistency and maintainability across the codebase.

---

## Standard Module Structure

Every module should follow this structure:

```rust
//! # Module Name
//! 
//! Brief description of what this module provides.
//! 
//! ## Features
//! 
//! - Feature 1
//! - Feature 2
//! 
//! ## Example
//! 
//! ```rust
//! // Example code
//! ```

// 1. Imports (organized by source)
use crate::core::error::Result;
use crate::utils::helpers::*;
use std::collections::HashMap;

// 2. Re-exports
pub use self::submodule::*;

// 3. Type definitions
pub struct MyType {
    field1: Type1,
    field2: Type2,
}

// 4. Implementations
impl MyType {
    /// Creates a new instance
    pub fn new() -> Self { /* ... */ }
}

// 5. Tests
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_something() { /* ... */ }
}
```

---

## Import Organization

Organize imports in this order:

```rust
// 1. Crate imports (internal)
use crate::core::error::Result;
use crate::utils::helpers::*;

// 2. External crate imports
use objc::runtime::Object;
use serde::{Deserialize, Serialize};

// 3. Standard library imports
use std::collections::HashMap;
use std::ffi::CString;
```

---

## Helper Functions

The `utils/helpers.rs` module provides common patterns to reduce duplication:

### Null Pointer Checks
```rust
use cocoanut::utils::helpers::check_not_null;

let ptr: *mut Object = /* ... */;
check_not_null(ptr, "NSButton")?;
```

### String Conversion
```rust
use cocoanut::utils::helpers::string_to_cstring_with_context;

let c_str = string_to_cstring_with_context("hello", "button title")?;
```

### Validation
```rust
use cocoanut::utils::helpers::{validate, validate_all};

validate(condition, "error message")?;

validate_all(vec![
    (condition1, "error 1"),
    (condition2, "error 2"),
])?;
```

### Safe Dereferencing
```rust
use cocoanut::utils::helpers::{safe_deref, safe_deref_mut};

let ref_value = unsafe { safe_deref(ptr, "MyType")? };
let mut_ref = unsafe { safe_deref_mut(ptr, "MyType")? };
```

---

## Documentation Standards

### Module Documentation
```rust
//! # Module Name
//! 
//! One-line description.
//! 
//! Longer description explaining the module's purpose and usage.
//! 
//! ## Features
//! 
//! - Feature 1: Description
//! - Feature 2: Description
//! 
//! ## Example
//! 
//! ```rust
//! use cocoanut::module_name::*;
//! 
//! // Example code
//! ```
```

### Type Documentation
```rust
/// Brief description (one line)
/// 
/// Longer description explaining what this type is and why you might use it.
/// 
/// # Fields
/// 
/// * `field1` - Description of field1
/// * `field2` - Description of field2
pub struct MyType {
    pub field1: Type1,
    pub field2: Type2,
}
```

### Method Documentation
```rust
/// Brief description (one line)
/// 
/// Longer description.
/// 
/// # Arguments
/// 
/// * `param1` - Description
/// * `param2` - Description
/// 
/// # Returns
/// 
/// Description of return value
/// 
/// # Errors
/// 
/// Description of possible errors
/// 
/// # Example
/// 
/// ```rust
/// let result = function_name(arg1, arg2)?;
/// ```
pub fn function_name(param1: Type1, param2: Type2) -> Result<ReturnType> {
    // Implementation
}
```

---

## Error Handling

### Error Messages

All error messages should be descriptive and actionable:

```rust
// Bad
Err(CocoanutError::InvalidParameter("Invalid"))

// Good
Err(CocoanutError::InvalidParameter(
    "Button title cannot be empty. Provide a non-empty string.".to_string()
))
```

### Using Helpers

```rust
use cocoanut::utils::helpers::check_not_null;

// Instead of:
if ptr.is_null() {
    return Err(CocoanutError::InvalidParameter("Null pointer".to_string()));
}

// Use:
check_not_null(ptr, "NSButton")?;
```

---

## Testing Standards

### Test Organization
```rust
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_basic_functionality() {
        // Arrange
        let input = setup();
        
        // Act
        let result = function_under_test(input);
        
        // Assert
        assert!(result.is_ok());
    }
    
    #[test]
    fn test_error_case() {
        let result = function_under_test(invalid_input);
        assert!(result.is_err());
    }
}
```

### Test Naming
- `test_basic_functionality` - Happy path
- `test_error_case` - Error handling
- `test_edge_case_*` - Boundary conditions
- `test_*_with_null` - Null pointer handling

---

## Naming Conventions

- **Types:** PascalCase (`Button`, `TextFieldBuilder`)
- **Functions:** snake_case (`create_button`, `set_title`)
- **Constants:** SCREAMING_SNAKE_CASE (`MAX_WIDTH`, `DEFAULT_HEIGHT`)
- **Variables:** snake_case (`button_width`, `is_enabled`)
- **Modules:** snake_case (`components`, `core_fixes`)

---

## Public API Surface

### Prelude Module

The `prelude` module exports the most commonly used types and functions:

```rust
pub mod prelude {
    // Core types
    pub use crate::core::error::Result;
    
    // Helpers
    pub use crate::utils::helpers::*;
    
    // Components
    pub use crate::components::*;
    
    // High-level API
    pub use crate::simple_app::*;
}
```

### Module Exports

Each module should re-export its public items:

```rust
// In module/mod.rs
pub mod submodule1;
pub mod submodule2;

pub use submodule1::*;
pub use submodule2::*;
```

---

## Code Review Checklist

- [ ] Module has documentation
- [ ] All public items are documented
- [ ] Code follows naming conventions
- [ ] Error messages are descriptive
- [ ] Helper functions are used where applicable
- [ ] Tests are comprehensive
- [ ] No unused imports
- [ ] Code is formatted with `cargo fmt`
- [ ] No clippy warnings

---

## Examples

### Well-Structured Module

```rust
//! Button component for macOS applications
//! 
//! Provides a simple button control with click event support.

use crate::core::error::Result;
use crate::utils::helpers::*;
use objc::runtime::Object;

/// A clickable button component
/// 
/// # Example
/// 
/// ```rust
/// let button = Button::new("Click me")?;
/// button.set_size(100.0, 40.0)?;
/// ```
pub struct Button {
    ns_button: *mut Object,
    id: String,
}

impl Button {
    /// Creates a new button with the specified title
    pub fn new(title: &str) -> Result<Self> {
        check_not_null(title as *const _ as *mut _, "title")?;
        
        let c_str = string_to_cstring_with_context(title, "button title")?;
        
        // Create button...
        Ok(Self {
            ns_button: std::ptr::null_mut(),
            id: "button".to_string(),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_button_creation() {
        let button = Button::new("Test");
        assert!(button.is_ok());
    }
}
```

---

## Benefits

✅ **Consistency** - All modules follow the same structure  
✅ **Maintainability** - Easy to understand and modify  
✅ **Discoverability** - Clear organization and naming  
✅ **Quality** - Comprehensive documentation and tests  
✅ **Reusability** - Helper functions reduce duplication  

---

**Last Updated:** October 25, 2025  
**Version:** 1.0  
**Status:** Active