Saltar al contenido

Un tipo por cosa, y cómo se organiza

El estado se identifica por su tipo, así que la organización del estado es una decisión de tipos. Cómo se reparte cuando son ocho cosas, por qué un tipo gordo es peor que ocho pequeños, y qué gana la firma de cada comando.

Los dos repartos

Rust
// A · un tipo grande con todo dentropub struct AppState {    pub db: Mutex<Connection>,    pub sesion: Mutex<Option<Sesion>>,    pub cache: Mutex<HashMap<ProyectoId, Portada>>,    pub trabajos: Mutex<HashMap<TrabajoId, CancellationToken>>,    pub config: Config,}// B · un tipo por cosapub struct Db(pub Mutex<Connection>);pub struct SesionActual(pub Mutex<Option<Sesion>>);pub struct CachePortadas(pub Mutex<HashMap<ProyectoId, Portada>>);pub struct Trabajos(pub Mutex<HashMap<TrabajoId, CancellationToken>>);pub struct Ajustes(pub Config);   // no muta: sin envoltura

El envoltorio de una sola cosa

La forma pub struct Db(pub Mutex<Connection>) es un patrón de Rust que aquí hace tres trabajos:

Da identidad al tipo. Sin él no podrías tener dos cosas que por dentro sean el mismo tipo, que es la limitación del nivel 16.2.

Le pone nombre a la intención. Db dice más que Mutex<Connection>, y en la firma de un comando la diferencia se lee.

Permite añadirle métodos. Y aquí está lo que más devuelve a medio plazo:

Rust
impl CachePortadas {    pub fn get(&self, id: ProyectoId) -> Option<Portada> {        self.0.lock().unwrap().get(&id).cloned()    }    pub fn put(&self, id: ProyectoId, p: Portada) {        self.0.lock().unwrap().insert(id, p);    }}

Con esos dos métodos, el cerrojo deja de aparecer en los comandos. Y con él desaparecen las dos formas de equivocarse del nivel 22.2: nadie puede sostenerlo a través de un punto de espera ni volver a tomarlo, porque nadie lo toma directamente.

Es la corrección más rentable de toda la fase IV: encapsular el cerrojo dentro del tipo de estado.

Dónde viven los tipos

Junto a su dominio, no en un fichero de estado:

TXT
src-tauri/src/├── lib.rs                 registra: .manage(Db(...)).manage(Trabajos(...))…├── proyectos/│   ├── estado.rs          CachePortadas, con sus métodos│   ├── comandos.rs│   └── logica.rs├── sesion/│   └── estado.rs          SesionActual└── db/    └── estado.rs          Db

Un fichero estado.rs global que reúne los ocho tipos parece ordenado y produce lo mismo que el struct grande: un sitio donde todo el mundo tiene que tocar. El estado de un dominio es del dominio.

Lo único que se junta es el registro, en lib.rs, que es la lista de lo que la aplicación gestiona — igual que la lista de comandos del nivel 14.2 es el inventario de la superficie, esta es el inventario del estado.