Claude
Skills
Sign in
Back

rust-ui-architecture

Included with Lifetime
$97 forever

Architecture patterns for Rust UI applications including GPUI-specific patterns, code organization, modularity, and scalability. Use when user needs guidance on application architecture, code organization, or scaling UI applications.

Design

What this skill does


# Rust UI Architecture

## Metadata

This skill provides comprehensive guidance on architecting scalable, maintainable Rust UI applications using GPUI, covering project structure, design patterns, and best practices.

## Instructions

### Application Structure

#### Recommended Project Layout

```
my-gpui-app/
├── Cargo.toml
├── src/
│   ├── main.rs                 # Application entry point
│   ├── app.rs                  # Main application struct
│   ├── ui/                     # UI layer
│   │   ├── mod.rs
│   │   ├── views/              # High-level views
│   │   │   ├── mod.rs
│   │   │   ├── main_view.rs
│   │   │   ├── sidebar.rs
│   │   │   └── editor.rs
│   │   ├── components/         # Reusable components
│   │   │   ├── mod.rs
│   │   │   ├── button.rs
│   │   │   ├── input.rs
│   │   │   └── modal.rs
│   │   └── theme.rs           # Theme definitions
│   ├── models/                 # Application state
│   │   ├── mod.rs
│   │   ├── document.rs
│   │   ├── project.rs
│   │   └── settings.rs
│   ├── services/              # External integrations
│   │   ├── mod.rs
│   │   ├── file_service.rs
│   │   └── api_client.rs
│   ├── domain/                # Core business logic
│   │   ├── mod.rs
│   │   └── operations.rs
│   └── utils/                 # Utilities
│       ├── mod.rs
│       └── helpers.rs
├── examples/                   # Example applications
│   └── basic.rs
└── tests/                     # Integration tests
    ├── integration/
    └── ui/
```

### Layer Separation

#### Four-Layer Architecture

```
┌─────────────────────────────────┐
│     UI Layer (Views)            │  - GPUI views and components
│                                 │  - User interactions
│                                 │  - Render logic
├─────────────────────────────────┤
│   Application Layer (Models)    │  - Application state (Model<T>)
│                                 │  - State coordination
│                                 │  - Business logic orchestration
├─────────────────────────────────┤
│    Service Layer (Services)     │  - File I/O
│                                 │  - Network requests
│                                 │  - External APIs
├─────────────────────────────────┤
│     Domain Layer (Core)         │  - Pure business logic
│                                 │  - Domain types
│                                 │  - No dependencies on UI/GPUI
└─────────────────────────────────┘
```

#### Example Implementation

```rust
// Domain Layer (pure logic)
pub mod domain {
    #[derive(Clone, Debug)]
    pub struct Document {
        pub id: DocumentId,
        pub content: String,
        pub language: Language,
    }

    impl Document {
        pub fn word_count(&self) -> usize {
            self.content.split_whitespace().count()
        }

        pub fn is_empty(&self) -> bool {
            self.content.trim().is_empty()
        }
    }
}

// Service Layer (external integration)
pub mod services {
    use super::domain::*;

    pub trait FileService: Send + Sync {
        fn read(&self, path: &Path) -> Result<String>;
        fn write(&self, path: &Path, content: &str) -> Result<()>;
    }

    pub struct RealFileService;

    impl FileService for RealFileService {
        fn read(&self, path: &Path) -> Result<String> {
            std::fs::read_to_string(path)
                .map_err(|e| anyhow::anyhow!("Failed to read: {}", e))
        }

        fn write(&self, path: &Path, content: &str) -> Result<()> {
            std::fs::write(path, content)
                .map_err(|e| anyhow::anyhow!("Failed to write: {}", e))
        }
    }
}

// Application Layer (state management)
pub mod models {
    use super::domain::*;
    use super::services::*;

    pub struct DocumentModel {
        document: Document,
        file_service: Arc<dyn FileService>,
        is_modified: bool,
    }

    impl DocumentModel {
        pub fn new(document: Document, file_service: Arc<dyn FileService>) -> Self {
            Self {
                document,
                file_service,
                is_modified: false,
            }
        }

        pub fn update_content(&mut self, content: String) {
            self.document.content = content;
            self.is_modified = true;
        }

        pub async fn save(&mut self) -> Result<()> {
            self.file_service.write(&self.document.path, &self.document.content)?;
            self.is_modified = false;
            Ok(())
        }
    }
}

// UI Layer (views)
pub mod ui {
    use gpui::*;
    use super::models::*;

    pub struct DocumentView {
        model: Model<DocumentModel>,
        _subscription: Subscription,
    }

    impl DocumentView {
        pub fn new(model: Model<DocumentModel>, cx: &mut ViewContext<Self>) -> Self {
            let _subscription = cx.observe(&model, |_, _, cx| cx.notify());
            Self { model, _subscription }
        }
    }

    impl Render for DocumentView {
        fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
            let model = self.model.read(cx);

            div()
                .child(format!("Words: {}", model.document.word_count()))
                .when(model.is_modified, |this| {
                    this.child("(modified)")
                })
        }
    }
}
```

### Component Hierarchies

#### Container-Presenter Pattern

```rust
// Container: Manages state and logic
pub struct EditorContainer {
    document: Model<DocumentModel>,
    _subscription: Subscription,
}

impl EditorContainer {
    pub fn new(document: Model<DocumentModel>, cx: &mut ViewContext<Self>) -> Self {
        let _subscription = cx.observe(&document, |_, _, cx| cx.notify());
        Self { document, _subscription }
    }

    fn handle_save(&mut self, cx: &mut ViewContext<Self>) {
        let document = self.document.clone();

        cx.spawn(|_, mut cx| async move {
            cx.update_model(&document, |doc, _| {
                doc.save().await
            }).await?;

            Ok::<_, anyhow::Error>(())
        }).detach();
    }
}

impl Render for EditorContainer {
    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
        let doc = self.document.read(cx);

        EditorPresenter::new(
            doc.document.content.clone(),
            doc.is_modified,
            cx.listener(|this, content, cx| {
                this.document.update(cx, |doc, _| {
                    doc.update_content(content);
                });
            }),
        )
    }
}

// Presenter: Pure rendering
pub struct EditorPresenter {
    content: String,
    is_modified: bool,
    on_change: Box<dyn Fn(String, &mut WindowContext)>,
}

impl EditorPresenter {
    pub fn new(
        content: String,
        is_modified: bool,
        on_change: impl Fn(String, &mut WindowContext) + 'static,
    ) -> Self {
        Self {
            content,
            is_modified,
            on_change: Box::new(on_change),
        }
    }
}

impl Render for EditorPresenter {
    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
        div()
            .flex()
            .flex_col()
            .child(
                textarea()
                    .value(&self.content)
                    .on_input(|value, cx| {
                        (self.on_change)(value, cx);
                    })
            )
            .when(self.is_modified, |this| {
                this.child("Unsaved changes")
            })
    }
}
```

### Module Organization

#### Feature-Based Structure

```
src/
├── features/
│   ├── editor/
│   │   ├── mod.rs
│   │   ├── model.rs          # EditorModel
│   │   ├── view.rs           # EditorView
│   │   ├── commands.rs       # Editor actions
│   │   └── components/       # Editor-specific components
│   ├── sidebar/
│   │   ├── mod.rs
│   │   ├── model.rs
│   │   ├── view.rs
│   │   └── components/
│   └── statusbar/
│       ├── mod.rs
│       ├── model.rs
│       └── view.rs
```

**Benefits**:
- Clear feature bou

Related in Design