warlocks_cauldron/providers/spec/
pt_br.rs

1use std::iter::zip;
2
3use super::super::dependencies::*;
4
5
6/// Methods collection provides special data for Brazil (pt-br)
7pub struct BrazilSpecProvider;
8
9impl BrazilSpecProvider {
10    /// Calculate the verifying digit for the CPF
11    fn get_verifying_digit_cpf(cpf: &Vec<u32>, peso: u32) -> u32 {
12        let mut soma = 0;
13        for (index, digit) in cpf.iter().enumerate() {
14            soma += digit * (peso - index as u32);
15        }
16
17        let resto = soma % 11;
18
19        if resto == 0 || resto == 1 || resto >= 11 {
20            0
21        } else {
22            11 - resto
23        }
24    }
25
26    /// Get a random CPF
27    pub fn cpf(with_mask: bool) -> String {
28        let mut cpf_without_dv = randints(0, 9, 9);
29        let first_dv = Self::get_verifying_digit_cpf(&cpf_without_dv, 10);
30
31        cpf_without_dv.push(first_dv);
32        let second_dv = Self::get_verifying_digit_cpf(&cpf_without_dv, 11);
33        cpf_without_dv.push(second_dv);
34
35        let cpf = cpf_without_dv.into_iter().join("");
36
37        match with_mask {
38            true => format!("{}.{}.{}-{}", &cpf[..3], &cpf[3..6], &cpf[6..9], &cpf[9..]),
39            false => cpf,
40        }
41    }
42
43    /// Calculate the verifying digit for the CNPJ
44    fn get_verifying_digit_cnpj(cnpj: &Vec<u32>, peso: u32) -> u32 {
45        let peso_list = match peso {
46            5 => vec![5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2],
47            6 => vec![6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2],
48            _ => panic!("Invalid peso!"),
49        };
50
51        let resto = zip(cnpj, peso_list).map(|(c, p)| c * p).sum::<u32>() % 11;
52
53        if resto < 2 {
54            0
55        } else {
56            11 - resto
57        }
58    }
59
60    /// Get a random CNPJ
61    pub fn cnpj(with_mask: bool) -> String {
62        let mut cnpj_without_dv = randints(0, 9, 12);
63
64        let first_dv = Self::get_verifying_digit_cnpj(&cnpj_without_dv, 5);
65        cnpj_without_dv.push(first_dv);
66
67        let second_dv = Self::get_verifying_digit_cnpj(&cnpj_without_dv, 6);
68        cnpj_without_dv.push(second_dv);
69
70        let cnpj = cnpj_without_dv.into_iter().join("");
71
72        match with_mask {
73            true => format!("{}.{}.{}/{}-{}", &cnpj[..2], &cnpj[2..5], &cnpj[5..8], &cnpj[8..12], &cnpj[12..]),
74            false => cnpj,
75        }
76    }
77}