|
7 | 7 | </h3> </td> |
8 | 8 | </tr></table> |
9 | 9 |
|
10 | | ---- |
11 | 10 |
|
12 | | -# **Common** 👨🏻🏭 |
| 11 | +--- |
13 | 12 |
|
14 | | -The Architectural Core of Land |
| 13 | +# **Common** 👨🏻🏭 |
15 | 14 |
|
16 | | -[](https://github.com/CodeEditorLand/Common/tree/Current/LICENSE) |
17 | | -[<img src="https://cdn.simpleicons.org/rust" width="14" alt="Rust" />](https://www.rust-lang.org/) [](https://www.rust-lang.org/) |
18 | | -[<img src="https://cdn.simpleicons.org/rust" width="14" alt="Rust" />](https://www.rust-lang.org/) [](https://crates.io/crates/land-common) |
19 | | - |
20 | | -Welcome to **Common**! This crate is the architectural heart of the Land Code |
21 | | -Editor's native backend. It provides a pure, abstract foundation for building |
22 | | -application logic using a declarative, effects-based system. It contains **no |
23 | | -concrete implementations**; instead, it defines the "language" of the |
24 | | -application through a set of powerful, composable building blocks. |
25 | | - |
26 | | -The entire `Mountain` backend and any future native components are built by |
27 | | -implementing the traits and consuming the effects defined in this crate. |
28 | | - |
29 | | -**What Common gives you:** |
30 | | - |
31 | | -1. **Test without Tauri.** Every capability is an abstract trait. Mock the trait, |
32 | | - test your logic. No window, no webview, no sidecar needed. |
33 | | -2. **Bugs at compile time.** The `ActionEffect` type describes operations as |
34 | | - values. The compiler catches missing dependencies and type mismatches before |
35 | | - runtime. |
36 | | -3. **One error enum, everywhere.** `CommonError` covers every failure domain. |
37 | | - No stringly-typed errors, no `unwrap()` surprises. |
38 | | -4. **Stable IPC contracts.** DTOs are `serde`-compatible and shared across |
39 | | - Mountain, Cocoon, and Wind. Change the type, and every consumer gets a |
40 | | - compile error. |
| 15 | +> **VS Code's codebase imports concrete implementations directly. Testing a single component means mocking entire subsystems. There is no dependency injection at the architecture level.** |
41 | 16 |
|
42 | | -📖 **[Rust API Documentation](https://Rust.Documentation.Editor.Land/Common/)** |
| 17 | +_"Mock any service and test any element in isolation, no running editor required."_ |
43 | 18 |
|
44 | | ---- |
| 19 | +[](https://github.com/CodeEditorLand/Common/tree/Current/LICENSE) |
| 20 | +[<img src="https://editor.land/Image/Rust.svg" width="14" alt="Rust" />](https://www.rust-lang.org/) [](https://www.rust-lang.org/) |
| 21 | +[<img src="https://editor.land/Image/Rust.svg" width="14" alt="Rust" />](https://www.rust-lang.org/) [](https://crates.io/crates/land-common) |
45 | 22 |
|
46 | | -## Key Features & Concepts 🔐 |
| 23 | +Common defines pure abstract traits with zero concrete implementations. Every element builds on Common's typed effects and composable building blocks. The Rust compiler enforces contracts at build time. If an element changes its signature, every consumer fails to compile immediately. Tests run in milliseconds because you can mock any trait and test any element without launching a window, a WebView, or a sidecar. |
47 | 24 |
|
48 | | -- **Declarative effects, not callbacks.** Operations are data. Describe what |
49 | | - you want, compose effects, then run them. Testing is trivial: just inspect |
50 | | - the effect value without executing it. |
51 | | -- **Compile-time dependency injection.** The `Environment` and `Requires` traits |
52 | | - wire dependencies at compile time. No runtime reflection, no service locator. |
53 | | -- **Async-first.** Every service trait (`FileSystemReader`, `CommandExecutor`, |
54 | | - etc.) is `async`. No blocking calls anywhere in the contract. |
55 | | -- **Shared DTOs for all IPC.** Mountain, Cocoon, and Wind all use the same |
56 | | - `serde`-compatible types. Schema changes break at compile time, not at runtime. |
57 | | -- **One error type.** `CommonError` covers all 20 service domains. Pattern match |
58 | | - once, handle every case. |
| 25 | +📖 **[Rust API Documentation](https://Rust.Documentation.Editor.Land/Common/)** |
59 | 26 |
|
60 | 27 | --- |
61 | 28 |
|
62 | | -## Core Architecture Principles 🏗️ |
| 29 | +## What It Does 🔐 |
63 | 30 |
|
64 | | -| Principle | Description | Key Components Involved | |
65 | | -| :----------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------- | |
66 | | -| **Abstraction** | Define every application capability as an abstract `async trait`. Never include concrete implementation logic. | All `*Provider.rs` and `*Manager.rs` files | |
67 | | -| **Declarativism** | Represent every operation as an `ActionEffect` value. The crate provides constructor functions for these effects. | `Effect/*`, all effect constructor files | |
68 | | -| **Composability** | The `ActionEffect` system and trait-based DI are designed to be composed, allowing complex workflows to be built from simple, reusable pieces. | `Environment/*`, `Effect/*` | |
69 | | -| **Contract-First** | Define all data structures (`DTO/*`) and error types (`Error/*`) first. These form the stable contract for all other components. | `DTO/`, `Error/` | |
70 | | -| **Purity** | This crate has minimal dependencies and is completely independent of Tauri, gRPC, or any specific application logic. | `Cargo.toml` | |
| 31 | +- **Pure abstract traits.** Zero concrete implementations. Every cross-element boundary is a typed contract. |
| 32 | +- **Compile-time enforcement.** Change a trait signature and every consumer fails to compile immediately. |
| 33 | +- **Millisecond tests.** Mock any trait and test any element without launching a window or WebView. |
| 34 | +- **ActionEffect system.** Declarative effects that are composable, testable, and type-safe. |
71 | 35 |
|
72 | 36 | --- |
73 | 37 |
|
74 | | -## The `ActionEffect` System Explained |
75 | | - |
76 | | -The core pattern in `Common` is the `ActionEffect`. Instead of writing a |
77 | | -function that immediately performs a side effect, you call a function that |
78 | | -_returns a description of that effect_. |
| 38 | +## In the Ecosystem 👨🏻🏭 + 🏞️ |
79 | 39 |
|
80 | | -**Traditional (Imperative) Approach:** |
| 40 | +```mermaid |
| 41 | +graph LR |
| 42 | + classDef Mountain fill:#f9f,stroke:#333,stroke-width:2px; |
| 43 | + classDef Common fill:#cfc,stroke:#333,stroke-width:1px; |
| 44 | + classDef Consumer fill:#9cf,stroke:#333,stroke-width:2px; |
81 | 45 |
|
82 | | -```rust |
83 | | -async fn read_my_file(fs: &impl FileSystem) -> Result<Vec<u8>, Error> { |
84 | | -// The side effect happens here. |
85 | | - fs.read("/path/to/file").await |
86 | | -} |
87 | | -``` |
| 46 | + subgraph "The \`Common\` Crate" |
| 47 | + direction LR |
| 48 | + Traits["Abstract Traits (e.g., \`FileSystemReader\`)"]:::Common |
| 49 | + Effects["ActionEffects (e.g., \`ReadFile\`)"]:::Common |
| 50 | + DTOs["Data Transfer Objects (e.g., \`FileTypeDTO\`)"]:::Common |
88 | 51 |
|
89 | | -**The `Common` (Declarative) Approach:** |
| 52 | + Effects -- Depend on --> Traits |
| 53 | + end |
90 | 54 |
|
91 | | -```rust |
92 | | -use CommonLibrary::FileSystem; |
93 | | -use std::sync::Arc; |
| 55 | + subgraph "Consumers" |
| 56 | + Mountain[**Mountain Application**]:::Mountain |
| 57 | + Tests[Unit & Integration Tests]:::Consumer |
| 58 | + end |
94 | 59 |
|
95 | | -// 1. Create a description of the desired effect. No I/O happens here. |
96 | | -// The effect's type signature explicitly declares its dependency: `Arc<dyn FileSystemReader>`. |
97 | | -let read_effect: ActionEffect<Arc<dyn FileSystemReader>, _, _> = FileSystem::ReadFile(PathBuf::from("/path/to/file")); |
| 60 | + Mountain -- Implements --> Traits |
| 61 | + Mountain -- Executes --> Effects |
| 62 | + Mountain -- Uses --> DTOs |
98 | 63 |
|
99 | | -// 2. Later, in a separate part of the system (the runtime), execute it. |
100 | | -// The runtime will see that the effect needs a FileSystemReader, provide one from its |
101 | | -// environment, and run the operation. |
102 | | -let file_content = runtime.Run(read_effect).await?; |
| 64 | + Tests -- Mocks --> Traits |
| 65 | + Tests -- Verifies --> Effects |
103 | 66 | ``` |
104 | 67 |
|
105 | | -This separation makes the architecture flexible and testable. |
106 | | - |
107 | 68 | --- |
108 | 69 |
|
109 | | -## Project Structure Overview 🗺️ |
110 | | - |
111 | | -The `Common` crate is organized by service domain, with each domain containing |
112 | | -its trait definitions, DTOs, and effect constructors. |
| 70 | +## Project Structure 🗺️ |
113 | 71 |
|
114 | 72 | ``` |
115 | 73 | Common/ |
@@ -155,138 +113,31 @@ Common/ |
155 | 113 |
|
156 | 114 | --- |
157 | 115 |
|
158 | | -## Deep Dive & Architectural Patterns 🔬 |
159 | | - |
160 | | -To understand the core philosophy behind this crate and how its components work |
161 | | -together, please refer to the detailed technical breakdown in |
162 | | -[`Documentation/GitHub/DeepDive.md`](https://github.com/CodeEditorLand/Common/tree/Current/Documentation/GitHub/DeepDive.md). |
| 116 | +## Development 🛠️ |
163 | 117 |
|
164 | | -This document explains the `ActionEffect` system, the trait-based dependency |
165 | | -injection model, and provides a guide for adding new services to the |
166 | | -architecture. |
| 118 | +Common is a component of the Land workspace. Follow the |
| 119 | +[Land Repository](https://github.com/CodeEditorLand/Land) instructions to |
| 120 | +build and run. |
167 | 121 |
|
168 | 122 | --- |
169 | 123 |
|
170 | | -## How `Common` Fits into the `Land` Ecosystem 👨🏻🏭 + 🏞️ |
| 124 | +## License ⚖️ |
171 | 125 |
|
172 | | -`Common` is the foundational layer upon which the entire native backend is |
173 | | -built. It has no knowledge of its consumers, but they are entirely dependent on |
174 | | -it. |
175 | | - |
176 | | -```mermaid |
177 | | -graph LR |
178 | | - classDef Mountain fill:#f9f,stroke:#333,stroke-width:2px; |
179 | | - classDef Common fill:#cfc,stroke:#333,stroke-width:1px; |
180 | | - classDef Consumer fill:#9cf,stroke:#333,stroke-width:2px; |
181 | | -
|
182 | | - subgraph "The \`Common\` Crate" |
183 | | - direction LR |
184 | | - Traits["Abstract Traits (e.g., \`FileSystemReader\`)"]:::Common |
185 | | - Effects["ActionEffects (e.g., \`ReadFile\`)"]:::Common |
186 | | - DTOs["Data Transfer Objects (e.g., \`FileTypeDTO\`)"]:::Common |
187 | | -
|
188 | | - Effects -- Depend on --> Traits |
189 | | - end |
190 | | -
|
191 | | - subgraph "Consumers" |
192 | | - Mountain[**Mountain Application**]:::Mountain |
193 | | - Tests[Unit & Integration Tests]:::Consumer |
194 | | - end |
195 | | -
|
196 | | - Mountain -- Implements --> Traits |
197 | | - Mountain -- Executes --> Effects |
198 | | - Mountain -- Uses --> DTOs |
199 | | -
|
200 | | - Tests -- Mocks --> Traits |
201 | | - Tests -- Verifies --> Effects |
202 | | -``` |
203 | | - |
204 | | ---- |
205 | | - |
206 | | -## Getting Started 🚀 |
207 | | - |
208 | | -### Installation 📥 |
209 | | - |
210 | | -`Common` is intended to be used as a local path dependency within the `Land` |
211 | | -workspace. In `Mountain`'s `Cargo.toml`: |
212 | | - |
213 | | -```toml |
214 | | -[dependencies] |
215 | | -Common = { path = "../Common" } |
216 | | -``` |
217 | | - |
218 | | -### Usage 🚀 |
219 | | - |
220 | | -A developer working within the `Mountain` codebase would use `Common` as |
221 | | -follows: |
222 | | - |
223 | | -1. **Implement a Trait:** In `Mountain/Source/Environment/`, provide the |
224 | | - concrete implementation for a `Common` trait. |
225 | | - |
226 | | -```rust |
227 | | -// In Mountain/Source/Environment/FileSystemProvider.rs |
228 | | - |
229 | | -use CommonLibrary::FileSystem::{FileSystemReader, FileSystemWriter}; |
230 | | - |
231 | | -#[async_trait] |
232 | | -impl FileSystemReader for MountainEnvironment { |
233 | | - async fn ReadFile(&self, Path: &PathBuf) -> Result<Vec<u8>, CommonError> { |
234 | | - // ... actual `tokio::fs` call ... |
235 | | - } |
236 | | - |
237 | | - // ... |
238 | | -} |
239 | | -``` |
240 | | - |
241 | | -2. **Create and Execute an Effect:** In business logic, create and run an |
242 | | - effect. |
243 | | - |
244 | | -```rust |
245 | | -// In a Mountain service or command |
246 | | - |
247 | | -use CommonLibrary::FileSystem; |
248 | | -use CommonLibrary::Effect::ApplicationRunTime; |
249 | | - |
250 | | -async fn some_logic(runtime: Arc<impl ApplicationRunTime>) { |
251 | | - let path = PathBuf::from("/my/file.txt"); |
252 | | - let read_effect = FileSystem::ReadFile(path); |
253 | | - |
254 | | - match runtime.Run(read_effect).await { |
255 | | - Ok(content) => info!("File content length: {}", content.len()), |
256 | | - Err(e) => error!("Failed to read file: {:?}", e), |
257 | | - } |
258 | | -} |
259 | | -``` |
| 126 | +CC0 1.0 Universal. Public domain. No restrictions. |
| 127 | +[LICENSE](https://github.com/CodeEditorLand/Common/tree/Current/LICENSE) |
260 | 128 |
|
261 | 129 | --- |
262 | 130 |
|
263 | | -## License ⚖️ |
264 | | - |
265 | | -This project is released into the public domain under the **Creative Commons CC0 |
266 | | -Universal** license. |
267 | | - |
268 | | -You are free to use, modify, distribute, and build upon this work for any |
269 | | -purpose, without any restrictions. For the full legal text, see the |
270 | | -[`LICENSE`](https://github.com/CodeEditorLand/Common/tree/Current/) file. |
271 | | - |
272 | | ---- |
273 | | - |
274 | | -## Changelog 📜 |
275 | | - |
276 | | -Stay updated with our progress! See |
277 | | -[`CHANGELOG.md`](https://github.com/CodeEditorLand/Common/tree/Current/) for a |
278 | | -history of changes specific to **Common**. |
279 | | - |
280 | | ---- |
281 | | - |
282 | | - |
283 | 131 | ## See Also |
284 | 132 |
|
| 133 | +- [Common Documentation](https://editor.land/Doc/common) |
285 | 134 | - [Architecture Overview](https://editor.land/Doc/architecture) |
| 135 | +- [Why Rust](https://editor.land/Doc/why-rust) |
286 | 136 | - [Mountain](https://github.com/CodeEditorLand/Mountain) |
287 | 137 | - [Echo](https://github.com/CodeEditorLand/Echo) |
288 | 138 | - [Air](https://github.com/CodeEditorLand/Air) |
289 | 139 |
|
| 140 | + |
290 | 141 | ## Funding & Acknowledgements 🙏🏻 |
291 | 142 |
|
292 | 143 | **Common** is a core element of the **Land** ecosystem. This project is funded |
|
0 commit comments