Introducción
Los programas reales de Rust suelen reutilizar bibliotecas especializadas en lugar de implementar cada funcionalidad desde cero. Una biblioteca de Rust publicada se denomina crate, y un crate que utiliza su paquete es una dependencia. Elegir y agregar una dependencia de forma segura es una tarea habitual en el desarrollo con Rust.
En este laboratorio, agregará el analizador de argumentos de línea de comandos clap a un programa de saludo preparado. Hará dos pequeñas modificaciones en el código fuente, observará la ayuda y la validación generadas, y aprenderá las distintas funciones de Cargo.toml y Cargo.lock. La dependencia se descarga previamente durante la configuración para que la primera compilación sea rápida, pero agregarla al proyecto del laboratorio sigue siendo responsabilidad suya.
Agregar la dependencia con Cargo
En este paso, agregará clap al paquete preparado e inspeccionará el cambio que Cargo realiza en el manifiesto.
El proyecto se encuentra en /home/labex/project/hello-cli. Acceda a ese directorio antes de ejecutar comandos de Cargo:
cd /home/labex/project/hello-cli
Abra el manifiesto del paquete con nano:
nano Cargo.toml
Cargo.toml describe el paquete y sus dependencias directas. La tabla [dependencies] vacía indica que este proyecto actualmente solo utiliza la biblioteca estándar de Rust. Presione Ctrl+X para salir de nano sin modificar el archivo.
El comando cargo add actualiza de forma segura la tabla de dependencias. Agregue clap versión 4.6.7 y habilite su funcionalidad derive:
cargo add clap@4.6.7 --features derive
Una funcionalidad habilita una parte opcional de un crate. En este caso, derive habilita las macros que convierten estructuras y enumeraciones de Rust en analizadores de argumentos de línea de comandos. Cargo muestra las funcionalidades habilitadas con + y las deshabilitadas con -; las funcionalidades deshabilitadas no indican errores.
Vuelva a abrir el manifiesto:
nano Cargo.toml
La tabla de dependencias ahora contiene una línea con esta estructura:
clap = { version = "4.6.7", features = ["derive"] }
La versión es un requisito de compatibilidad. Cargo puede seleccionar una versión 4.x compatible más reciente, mientras que las versiones exactas seleccionadas se registran por separado en Cargo.lock. Presione Ctrl+X para cerrar nano.
Derivar un analizador de argumentos de línea de comandos
En este paso, conectará la estructura Cli con clap mediante una macro de derive y metadatos del comando.
Abra el archivo de código fuente preparado:
nano src/main.rs
Ya utilizó #[derive(Debug)] en el curso para principiantes. Una macro de derive solicita a un crate que genere una implementación de trait a partir de la estructura de un tipo. Reemplace el primer comentario TODO situado encima de struct Cli por estas dos líneas:
#[derive(Parser)]
#[command(version, about = "Create a friendly greeting")]
#[derive(Parser)] genera el comportamiento de análisis. El atributo #[command(...)] proporciona información sobre todo el comando: version lee la versión del paquete desde Cargo.toml, y about proporciona una descripción breve.
Guarde el archivo con Ctrl+O, presione Enter y salga con Ctrl+X. Compruebe el programa sin ejecutarlo:
cargo check
La primera comprobación compila clap y sus crates de apoyo, por lo que puede mostrar varias líneas Compiling y Checking. Una línea final que comience por Finished indica que la dependencia y el analizador generado se compilaron correctamente juntos.
Ahora solicite la ayuda del programa. El separador -- distingue las opciones de Cargo de los argumentos destinados a su programa:
cargo run --quiet -- --help
La salida incluye la descripción, un valor obligatorio <NAME> y las opciones de ayuda y versión generadas automáticamente:
Create a friendly greeting
Usage: hello-cli <NAME>
...
Usted escribió la estructura de datos; clap generó a partir de ella una ayuda coherente y la validación de los argumentos.
Agregar una opción de repetición
En este paso, agregará una opción tipada y utilizará el valor analizado en un bucle pequeño.
Ejecute primero el comando con un nombre posicional:
cargo run --quiet -- Ada
Hello, Ada!
name: String se convierte en un valor posicional obligatorio porque no tiene un atributo #[arg(...)]. Vuelva a abrir el código fuente:
nano src/main.rs
Reemplace el segundo comentario TODO dentro de Cli por:
/// Number of greetings to print
#[arg(short, long, default_value_t = 1)]
times: u8,
El comentario de documentación se convierte en el texto de ayuda. short crea -t, long crea --times y default_value_t = 1 proporciona un valor predeterminado tipado cuando se omite la opción. Como el campo es de tipo u8, clap también rechaza los valores que no sean enteros válidos sin signo de 8 bits.
Reemplace el comentario TODO final y la única línea println! por:
for _ in 0..cli.times {
println!("Hello, {}!", cli.name);
}
El guion bajo indica que el contador del bucle no se utiliza intencionadamente. Guarde el archivo, salga de nano y ejecute tres saludos:
cargo run --quiet -- Ada --times 3
Hello, Ada!
Hello, Ada!
Hello, Ada!
Pruebe también un valor no válido:
cargo run --quiet -- Ada --times many
Este comando debe fallar. clap muestra un error que explica que many no es un u8 válido y termina con un código distinto de cero antes de que main utilice un valor no válido.
Inspeccionar y reutilizar el grafo de dependencias bloqueado
En este paso, inspeccionará el grafo de dependencias resuelto por Cargo y comprobará que el archivo de bloqueo puede reproducirlo sin acceso a la red.
clap es su dependencia directa, pero utiliza sus propios crates de apoyo. Muestre el primer nivel del grafo resuelto:
cargo tree --depth 1
La versión exacta del parche puede ser más reciente que el requisito compatible de Cargo.toml. Lo importante es esta estructura:
hello-cli v0.1.0 (...)
└── clap v4...
Abra el archivo de bloqueo generado:
nano Cargo.lock
Cargo.lock contiene datos generados, por lo que normalmente no debe editarlo manualmente. Registra las versiones exactas y las sumas de comprobación que Cargo seleccionó para todo el grafo. En una aplicación como esta CLI, conserve el archivo de bloqueo junto con el proyecto para que sus compañeros y las compilaciones automatizadas puedan reutilizar la misma resolución. Presione Ctrl+X para cerrar nano.
Ahora exija tanto el archivo de bloqueo existente como la caché local de crates:
cargo check --locked --offline
--locked impide modificar Cargo.lock. --offline impide el acceso a la red. Una línea final Finished demuestra que el proyecto puede comprobarse usando el grafo de dependencias ya descargado, sin resolver silenciosamente versiones diferentes.
Resumen
Agregó una dependencia directa de crate con Cargo, habilitó una funcionalidad opcional, derivó un analizador tipado de clap y observó la ayuda y la validación automáticas. También distinguió entre el requisito compatible de Cargo.toml y el grafo exacto de dependencias de Cargo.lock, y comprobó que el grafo bloqueado funciona sin conexión.


