As facilidades de criar um programa de linha de comando com Rust

grubba

Gabriel Grubba

Posted on July 21, 2022

As facilidades de criar um programa de linha de comando com Rust

CLI

Por onde começar ?

Tudo que falarei nesse post está nesse link do github, se quiser baixar e ou acompanhar via github sinta-se a vontade.

Programas de linha de comando em rust podem usar uma dependencia chamada clap sua doc fica aqui 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.


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

    #[clap(parse(from_os_str))]
    path: std::path::PathBuf,
}
Enter fullscreen mode Exit fullscreen mode

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


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())
}

Enter fullscreen mode Exit fullscreen mode

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.

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

Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Texto zipado

Esse linguição de caracteres é o mesmo texto que foi passando anteriorimente.


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.

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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

💖 💪 🙅 🚩
grubba
Gabriel Grubba

Posted on July 21, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related