Ir al contenido
  1. Posts/

Todo CLI en Rust 4. Persistencia JSON, testing y decisiones para escalar

·2 mins
Rafael Fernandez
Autor
Rafael Fernandez
Matemáticas, programación y cosas de la vida
Todo CLI en Rust sin humo - Este artículo es parte de una serie.
Parte 4: Este artículo

Última parte.

Read this chapter in English: EN

Aquí cerramos con dos cosas que determinan si un proyecto aguanta iteraciones reales: persistencia y tests.

Código de referencia:

Puerto primero, implementación después
#

Antes de tocar disco, definimos el contrato TaskRepository.

Por qué esto en vez de llamar JSON desde casos de uso
#

Si el caso de uso conoce JSON:

  • depende de serde,
  • depende de rutas,
  • depende de errores de I/O,
  • y deja de ser caso de uso para convertirse en script de infraestructura.

Con puerto, aplicación solo conoce operaciones de negocio (save, find, list, delete).

Dos adapters, dos responsabilidades
#

InMemoryTaskRepository:

  • rápido,
  • ideal para tests de comportamiento,
  • sin latencia de filesystem.

JsonFileTaskRepository:

  • persistencia real,
  • serialización,
  • errores de lectura/escritura/parsing.

Esto permite testear cada cosa donde corresponde.

Decisiones técnicas de persistencia JSON
#

  1. Ruta de datos en directorio de configuración de plataforma (con directories).
  2. Creación de directorios si faltan (create_dir_all).
  3. Archivo ausente = estado vacío (caso normal de primera ejecución).
  4. JSON inválido = error explícito, no autocorrección silenciosa.

Por qué no autocorregir JSON corrupto
#

Porque “arreglar” de forma automática suele equivaler a perder datos sin aviso.

Preferimos fallar con contexto y dejar al usuario decidir recuperación.

Semántica que quedó estabilizada
#

  • save: upsert por id.
  • list: All o ByStatus.
  • find_by_id: Option<Task>.
  • delete: bool (si borró o no).

Este diseño simplifica la CLI porque evita mezclar errores reales con resultados esperables (not found en delete).

Estrategia de pruebas
#

Se testea en ambos adapters:

  • guardar y recuperar,
  • listar y filtrar,
  • delete existente/no existente,
  • persistencia entre instancias (JSON),
  • JSON inválido retorna error.

Con tempdir en JSON tests, no se toca filesystem real del usuario.

Commits que complementan esta parte
#

Si quieres ver el orden evolutivo:

Se ve bien cómo primero se implementa comportamiento y luego se endurece con pruebas.

Deuda técnica explícita (que no escondimos)
#

Hay cosas intencionalmente pendientes:

  • RepoError todavía es bastante genérico.
  • no hay locking de archivo para concurrencia.
  • no hay migración/versionado del JSON.

Para el alcance del reto está bien. Para escalar a multi-proceso o uso intensivo, serían los siguientes pasos.

Cierre de la serie
#

El proyecto empezó como “To-Do de consola” y terminó siendo un ejercicio completo de diseño en Rust:

  • dominio con invariantes,
  • casos de uso acotados,
  • adapters intercambiables,
  • contrato CLI usable,
  • y pruebas orientadas a comportamiento.

Ese es el verdadero valor del proyecto: usar algo pequeño para practicar decisiones grandes.

Todo CLI en Rust sin humo - Este artículo es parte de una serie.
Parte 4: Este artículo