Skip to content

Commit

Permalink
Adiciona documentação (#52)
Browse files Browse the repository at this point in the history
* descreve funções no README.md

* atualiza README.md

* adiciona documentação geral da lib

* adiciona documentação de CPF e corrige função is_masked

* adiciona documentação de CNPJ e corrige função is_masked

* adiciona documentação de CNH e corrige função is_masked

* adiciona documentação dos módulos docs e common

* pequeno ajuste na documentação
  • Loading branch information
brenomfviana authored Mar 16, 2024
1 parent 05b800b commit 5a8fab2
Show file tree
Hide file tree
Showing 9 changed files with 701 additions and 105 deletions.
91 changes: 76 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,32 @@
<img src="https://img.shields.io/github/issues/brenomfviana/brado" alt="latest release" />
</a>

Brado (BRAzilian DOcs validator) é um pacote Rust para validação de documentos brasileiros.

Este projeto é inspirado no [validate-docbr](https://github.com/alvarofpp/validate-docbr).
Brado é um pacote Rust para validação de documentos brasileiros. Este projeto é inspirado na biblioteca Python [validate-docbr](https://github.com/alvarofpp/validate-docbr).

Para adicionar o pacote ao projeto:
Brado fornece funções para identificação, validação e geração de documentos brasileiros. O nome desta biblioteca (Brado) é um acronimo de BRAzilian DOcs validator (validador de DOcumentos BRAsileiros).

```bash
cargo add brado
```
> :warning: A documentação desta biblioteca pode ser acessada [aqui](https://docs.rs/brado/).
A documentação pode ser acessada [aqui](https://docs.rs/brado/) (ainda em desenvolvimento).

## Guia Rápido

## Testes

Para rodar os testes, basta executar o comando a seguir:
Para adicionar o pacote ao projeto, basta rodar o seguinte comando:

```bash
cargo add brado
```
make test

Ou adicionar a linha a seguir no arquivo `Cargo.toml`:

```toml
brado = "0.3.5"
```


## Documentos

- [x] CPF: Cadastro de Pessoas Físicas;
- [x] CPF: Cadastro de Pessoa Física;
- [x] CNH: Carteira Nacional de Habilitação;
- [x] CNPJ: Cadastro Nacional da Pessoa Jurídica;
- [ ] CNS: Cartão Nacional de Saúde;
Expand All @@ -49,30 +51,80 @@ Todos os documentos possuem as mesmas funções e funcionam da mesma forma.

### validate

Valida o documento passado como parâmetro (`&str`). Retorna um valor booleano (`bool`), `true` caso o documento seja válido, ou `false` caso contrário.

```rust
use brado::cpf;

cpf::validate("63929247011"); // true
cpf::validate("639.292.470-11"); // true
cpf::validate("639.292.470-10"); // false

cpf::validate("63929247011"); // true
cpf::validate("63929247010"); // false
cpf::validate("639.292.470-10"); // false
```

### mask

Mascara o documento passado como parâmetro (`&str`). Retorna a string (`String`) correspondente ao documento mascarado. A string passada não deve possuir símbolos.

```rust
use brado::cpf;

cpf::mask("63929247011"); // "639.292.470-11"

cpf::mask("639.292.470-11"); // panic!
```

### is_bare

Verifica se o documento passado como parâmetro (`&str`) não possui símbolos. Retorna um valor booleano (`bool`), `true` caso o documento não possua símbolos, ou `false` caso contrário.

```rust
use brado::cpf;

cpf::is_bare("63929247011"); // true
cpf::is_bare("63929247010"); // true

cpf::is_bare("639.292.470-11"); // false
cpf::is_bare("639.29247011"); // false
cpf::is_bare("639292470110"); // false
```

> OBS: se for utilizada a função `cpf::is_bare` para verificar se um CNPJ não possui símbolos, o resultado será `false`! Isso acontece pois esta função considera que a string é um CPF, ou seja, possui 11 dígitos.
### is_masked

Verifica se o documento passado como parâmetro (`&str`) está mascarado de acordo com o documento correspondente. Retorna um valor booleano (`bool`), `true` caso o documento esteja mascarado, ou `false` caso contrário.

```rust
use brado::cpf;

cpf::is_masked("639.292.470-10"); // true

cpf::is_masked("63929247011"); // false
cpf::is_masked("6392.92.470-11"); // false
cpf::is_masked("639.292.470-110"); // false
```

> OBS: `cpf::is_masked` verifica se a string passada está mascarada como um CPF. `cnpj::is_masked` verifica se a string passada está mascarada como um CNPJ.
### generate

Gera um novo documento sem símbolos (`String`).

```rust
use brado::cpf;

cpf::generate(); // "639.292.470-11"
```

### generate_masked

Gera um novo documento mascarado (`String`).

```rust
use brado::cpf;

cpf::generate(); // "63929247011"
cpf::generate_masked(); // "639.292.470-11"
```

Expand All @@ -87,3 +139,12 @@ nix flake clone github:your-github-user/brado --dest ./brado \
&& cd brado 1>/dev/null 2>/dev/null \
&& direnv allow
```


## Testes

Para rodar os testes, basta executar o comando a seguir:

```bash
make test
```
158 changes: 136 additions & 22 deletions brado/src/cnh.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,44 @@
//! Utilitários para validação de CNH.
use crate::common::{
get_digits, get_symbols, is_repeated, random_digit_vector,
};

pub fn validate(cnh: &str) -> bool {
let size: usize = cnh.chars().count();

if size != 11 && !is_masked(cnh) {
/// Realiza validação de CNH, máscarado ou não.
/// Retorna `true` se o argumento `doc` for uma CNH válido,
/// caso contrário, retorna `false`.
///
/// ## Exemplos
///
/// CNHs válidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::validate("84718735264"); // true
/// assert!(result);
///
/// let result = cnh::validate("847 187 352 64"); // true
/// assert!(result);
/// ```
///
/// CNHs inválidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::validate("84718735265"); // false
/// assert!(!result);
///
/// let result = cnh::validate("847 187 352 65"); // false
/// assert!(!result);
/// ```
pub fn validate(doc: &str) -> bool {
let size: usize = doc.chars().count();

if size != 11 && !is_masked(doc) {
return false;
}

let digits: Vec<u16> = get_digits(cnh);
let digits: Vec<u16> = get_digits(doc);

if digits.len() != 11 {
return false;
Expand All @@ -24,9 +53,9 @@ pub fn validate(cnh: &str) -> bool {
(d10, d11) == (digits[9], digits[10])
}

fn generate_digits(cnh_slice: &[u16]) -> (u16, u16) {
let (d10, dsc): (u16, u16) = generate_first_digit(cnh_slice);
let d11: u16 = generate_second_digit(cnh_slice, dsc);
fn generate_digits(doc_slice: &[u16]) -> (u16, u16) {
let (d10, dsc): (u16, u16) = generate_first_digit(doc_slice);
let d11: u16 = generate_second_digit(doc_slice, dsc);

(d10, d11)
}
Expand All @@ -50,13 +79,13 @@ fn generate_first_digit(cnh: &[u16]) -> (u16, u16) {
}

fn generate_second_digit(
cnh: &[u16],
doc: &[u16],
dsc: u16,
) -> u16 {
let mut sum: u16 = 0;

for i in 1..=9 {
sum += cnh[i - 1] * (i as u16);
sum += doc[i - 1] * (i as u16);
}

let mut second: i16 = ((sum % 11) as i16) - (dsc as i16);
Expand All @@ -70,34 +99,110 @@ fn generate_second_digit(
second as u16
}

pub fn is_bare(cnh: &str) -> bool {
cnh.chars().count() == 11 && get_digits(cnh).len() == 11
/// Verifica se o argumento `doc` pode ser um CNH sem símbolos.
/// Se for, retorna `true`, caso contrário, retorna `false`.
///
/// ## Exemplos
///
/// CNHs válidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::is_bare("84718735264"); // true
/// assert!(result);
///
/// let result = cnh::is_bare("847 187 352 64"); // false
/// assert!(!result);
/// ```
///
/// CNHs inválidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::is_bare("84718735265"); // true
/// assert!(result);
/// ```
pub fn is_bare(doc: &str) -> bool {
doc.chars().count() == 11 && get_digits(doc).len() == 11
}

pub fn is_masked(cnh: &str) -> bool {
let symbols: Vec<(usize, char)> = get_symbols(cnh);

if symbols.len() != 3 {
/// Verifica se o argumento `doc` pode ser um CNH com símbolos.
/// Se for, retorna `true`, caso contrário, retorna `false`.
///
/// ## Exemplos
///
/// CNHs válidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::is_masked("847 187 352 64"); // true
/// assert!(result);
///
/// let result = cnh::is_masked("84718735264"); // false
/// assert!(!result);
/// ```
///
/// CNHs inválidos:
/// ```
/// use brado::cnh;
///
/// let result = cnh::is_masked("847 187 352 65"); // true
/// assert!(result);
/// ```
pub fn is_masked(doc: &str) -> bool {
let symbols: Vec<(usize, char)> = get_symbols(doc);
let digits: Vec<u16> = get_digits(doc);

if symbols.len() != 3 || digits.len() != 11 {
return false;
}

symbols[0] == (3, ' ') && symbols[1] == (7, ' ') && symbols[2] == (11, ' ')
}

pub fn mask(cnh: &str) -> String {
if !is_bare(cnh) {
/// Aplica máscara de CNH no argumento `doc` e retorna resultado.
/// O argumento deve ser uma string sem símbolos, caso contrário,
/// deve lançar erro.
///
/// ## Exemplos
///
/// Documento de 11 dígitos sem máscara:
/// ```
/// use brado::cnh;
///
/// let result = cnh::mask("84718735264"); // "847 187 352 64"
/// assert!(cnh::is_masked(&result)); // true
/// ```
///
/// Documento de 11 dígitos com máscara:
/// ```should_panic
/// use brado::cnh;
///
/// cnh::mask("847 187 352 64"); // panic!
/// ```
pub fn mask(doc: &str) -> String {
if !is_bare(doc) {
panic!("The given string cannot be masked as CNH!")
}

format!(
"{} {} {} {}",
&cnh[0..3],
&cnh[3..6],
&cnh[6..9],
&cnh[9..11],
&doc[0..3],
&doc[3..6],
&doc[6..9],
&doc[9..11],
)
}

/// Gera e retorna um CNH aleatório sem máscara.
///
/// ## Exemplo
/// ```
/// use brado::cnh;
///
/// let result = cnh::generate(); // "84718735264"
/// assert!(cnh::is_bare(&result)); // true
/// ```
pub fn generate() -> String {
let mut cnh: Vec<u16> = random_digit_vector(9);
let (d10, dsc): (u16, u16) = generate_first_digit(&cnh);
Expand All @@ -111,6 +216,15 @@ pub fn generate() -> String {
.join("")
}

/// Gera e retorna um CNH aleatório com máscara.
///
/// ## Exemplo
/// ```
/// use brado::cnh;
///
/// let result = cnh::generate_masked(); // "847 187 352 64"
/// assert!(cnh::is_masked(&result)); // true
/// ```
pub fn generate_masked() -> String {
mask(&generate())
}
Loading

0 comments on commit 5a8fab2

Please sign in to comment.