As facilidades de criar um programa de linha de comando com Rust
Tags: rust, tutorial, programming
Published: 2022-07-21 02:38:05


![CLI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83gcllzp3qweery9etxn.jpeg)


## Por onde começar ?

Tudo que falarei nesse post está nesse [link](https://github.com/Grubba27/rust-compacter) do github, se quiser baixar e ou acompanhar via github sinta-se a vontade.<br/>
Programas de linha de comando em rust podem usar uma dependencia chamada clap sua doc fica [aqui](https://docs.rs/clap/3.0.8/clap) ela pode ser utilizada para validar dados em linhas de comando.

## Como que se faz essa validação?

Usando a bibilioteca clap dessa forma aqui podemos ter um parser que fará quase todas as validações, desde tipo até de ordem. No nosso caso ele validará o comando que é uma string e um path.

```rust

#[derive(Parser)]
struct Args {
    command: String,

    #[clap(parse(from_os_str))]
    path: std::path::PathBuf,
}
```

*struct de onde o clap faz a validação*

## Qual programa faremos ?

Os conceitos que eu mostro aqui nesse post pode ser usado para fazer paticamente qualquer outro programa. Mas sem delongas, faremos um compactador(tipo o zip mesmo) e um descompactador para fazer o unzip do arquivo que zipamos. 


![ZIP](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16hm43i55u22g205et81.png)

```rust

fn main() -> std::io::Result<()> {
    let args: Args = Args::parse();

    let mut file_text: String = String::from("");
    let text = std::fs::read_to_string(&args.path).expect("File is wrong");

    if args.command == "zip" {
        zip_file(text, &mut file_text);
    } else if args.command == "unzip" {
        unzip_file(text, &mut file_text);
    }


    let file_path = format!("src/{}.txt", args.command);
    let mut file = File::create(file_path)?;
    file.write_all(&file_text.as_ref())
}

```
_Função main onde executamos nosso código e onde a maioria da mágica acontece_

### Explicando
Na função main, eu começo fazendo o parse dos argumentos na linha de comando, depois disso eu crio uma string mutavél onde armazenarei meu texto do arquivo, verifico se existe o texto no caminho onde o usuario passou, por fim verifico qual comando foi colocado e escrevo o file_text que é inserido no arquivo.

### Demonstrando
Para ficar mais claro o que foi feito, o texto abaixo é usado como 
input.

```text
Violetas são azuis
Rosas são vermelhas
Meu teclado não está funcionando
Ou será que eu não estou são?

```
_texto base_
com o comando _ cargo run zip src/text.txt _ sendo o text.txt esse texto ele irá gerar esse arquivo de texto:

```
Violet5121azuis0Ros5121vermelh50M41teclado1317á1funcionando0Ou1será1que141317612?0
```
_Texto zipado_

Esse linguição de caracteres é o mesmo texto que foi passando anteriorimente.
<br/>
Se rodarmos  _cargo run unzip src/zip.txt_ nesse texto ele ira fazer o caminho inverso e firará igual ao texto que foi feito no começo.

## Onde fica a mágica ?

A parte onde poderia se dizer que tem mágica é nas funções zip_file e unzip_file, onde como os propríos nomes já dizem, elas zipam e deszipam os arquivos. 

```rust
fn zip_file(text: String, file_text: &mut String) {
    for line in text.lines() {
        let compact = line
            .replace(" ", "1")
            .replace("são", "2")
            .replace("não", "3")
            .replace("eu", "4")
            .replace("as", "5")
            .replace("ou", "6")
            .replace("est", "7");
        let result = compact + "0";
        file_text.push_str(&*result);
    }
}

fn unzip_file(text: String, file_text: &mut String) {
    for line in text.lines() {
        let compact = line
            .replace("0", "\n")
            .replace("1", " ")
            .replace("2", "são")
            .replace("3", "não")
            .replace("4", "eu")
            .replace("5", "as")
            .replace("6", "ou")
            .replace("7", "est");
        file_text.push_str(&*compact);
    }
}
```

_Funções de compactação e descompactação_

Como pode ser observado, cada simbolo especifíco como o 3 que significa não, subsitui naquele texto e gera um texto menor e com menos repetições, o que acaba por deixa-lo menor. 

### Esses simbolos vem da onde ?
Os caracteres &* tem significados únicos, o & siginifca a refêrencia de uma váriavelm já o * o ponteiro. 

## Conclusão

Depois de ler essa publicação e entender pelo menos um pouco do código em Rust, pode-se dizer que além de ser uma linguagem extremamente bonita, é versátil ao ponto de ser uma ótima opção para criar programas de linha de comando. Caso queira saber mais sobre compactadores e descompactadores tem esse ótimo vídeo sobre esse assunto [link](https://www.youtube.com/watch?v=Lto-ajuqW3w)