validador_br/
validador.rs

1use crate::funcoes::{calc_digito, calc_digito_mod11, completa_esquerda, mod_11, 
2onze_menos_mod11, somente_digitos,
3};
4
5use crate::types::{CartaoCredito, Cnh, Cnpj, Cns, CodigoBarrasGs1, Cpf, Pis, Renavam, 
6Rg, TipoCns, TituloEleitor,
7};
8
9pub trait Validador {
10    fn is_valid(_numero: &str) -> bool {
11        false
12    }
13
14    fn validar(&self) -> bool;
15}
16
17impl Validador for Cpf<'_> {
18    fn is_valid(numero: &str) -> bool {
19        let multiplicadores = vec![10, 9, 8, 7, 6, 5, 4, 3, 2];
20        let digitos = somente_digitos(numero, 11);
21        let part1 = digitos[0..9].to_vec();
22        let dv1 = &digitos[9];
23        let part2 = digitos[1..10].to_vec();
24        let dv2 = &digitos[10];
25        let decima = |x: u32| mod_11(10 * x) as u32;
26
27        let digitos_verificadores: (u32, u32) = (
28            calc_digito(part1, multiplicadores.clone(), decima),
29            calc_digito(part2, multiplicadores, decima),
30        );
31        digitos_verificadores == (*dv1, *dv2)
32    }
33
34    fn validar(&self) -> bool {
35        Self::is_valid(self.0)
36    }
37}
38
39impl Validador for Cnpj<'_> {
40    fn is_valid(numero: &str) -> bool {
41        let multiplicadores1 = vec![5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
42        let digitos = somente_digitos(numero, 14);
43        let part1 = digitos[0..12].to_vec();
44        let dv1 = &digitos[12];
45        let multiplicadores2 = vec![6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
46        let part2 = digitos[0..13].to_vec();
47        let dv2 = &digitos[13];
48        let decima = |x: u32| mod_11(10 * x) as u32;
49
50        let digitos_verificadores: (u32, u32) = (
51            calc_digito(part1, multiplicadores1, decima),
52            calc_digito(part2, multiplicadores2, decima),
53        );
54        digitos_verificadores == (*dv1, *dv2)
55    }
56
57    fn validar(&self) -> bool {
58        Self::is_valid(self.0)
59    }
60}
61
62impl Validador for CartaoCredito<'_> {
63    fn is_valid(numero: &str) -> bool {
64        let mut numbers = somente_digitos(numero, numero.len());
65        numbers.reverse();
66        let mut is_odd: bool = true;
67        let mut odd_sum: u32 = 0;
68        let mut even_sum: u32 = 0;
69        for digit in numbers {
70            if is_odd {
71                odd_sum += digit;
72            } else {
73                even_sum += digit / 5 + (2 * digit) % 10;
74            }
75            is_odd = !is_odd
76        }
77
78        (odd_sum + even_sum) % 10 == 0
79    }
80
81    fn validar(&self) -> bool {
82        Self::is_valid(self.0)
83    }
84}
85
86impl Validador for TituloEleitor<'_> {
87    fn is_valid(numero: &str) -> bool {
88        let multiplicadores1 = vec![2, 3, 4, 5, 6, 7, 8, 9];
89        let digitos = somente_digitos(numero, 12);
90        let part1 = digitos[0..8].to_vec();
91        let dv1 = &digitos[10];
92        let multiplicadores2 = vec![7, 8, 9];
93        let part2 = digitos[8..11].to_vec();
94        let dv2 = &digitos[11];
95
96        let digitos_verificadores: (u32, u32) = (
97            calc_digito_mod11(part1, multiplicadores1),
98            calc_digito_mod11(part2, multiplicadores2),
99        );
100        digitos_verificadores == (*dv1, *dv2)
101    }
102
103    fn validar(&self) -> bool {
104        Self::is_valid(self.0)
105    }
106}
107
108impl Validador for Cnh<'_> {
109    fn is_valid(numero: &str) -> bool {
110        let multiplicadores1 = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
111        let digitos = somente_digitos(numero, 11);
112        let part1 = digitos[0..9].to_vec();
113        let dv1 = &digitos[9];
114        let multiplicadores2 = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
115        let part2 = digitos[0..9].to_vec();
116        let dv2 = &digitos[10];
117
118        let mut verifica1 = calc_digito(part1, multiplicadores1, |x| x);
119        let delta: u32 = if verifica1 % 11 == 10 { 2 } else { 0 };
120        verifica1 = mod_11(verifica1) as u32;
121
122        let verificador_final = |soma: u32| {
123            let mod11 = soma % 11;
124            let res = match Some(mod11 - delta) {
125                Some(x) => x,
126                None => 11 + mod11 - delta,
127            };
128            if res > 9 {
129                0
130            } else {
131                res
132            }
133        };
134
135        let mut verifica2 = calc_digito(part2, multiplicadores2, |x| x);
136        verifica2 = verificador_final(verifica2);
137
138        (verifica1, verifica2) == (*dv1, *dv2)
139    }
140
141    fn validar(&self) -> bool {
142        Self::is_valid(self.0)
143    }
144}
145
146impl Validador for Renavam<'_> {
147    fn is_valid(numero: &str) -> bool {
148        let multiplicadores1 = vec![3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
149        let mut digitos = somente_digitos(numero, 11);
150        completa_esquerda(&mut digitos, 11);
151        let dv1 = digitos.split_off(10);
152
153        dv1[0] == calc_digito(digitos, multiplicadores1, onze_menos_mod11)
154    }
155
156    fn validar(&self) -> bool {
157        Self::is_valid(self.0)
158    }
159}
160
161impl Validador for Rg<'_> {
162    fn is_valid(numero: &str) -> bool {
163        let multiplicadores1 = vec![2, 3, 4, 5, 6, 7, 8, 9];
164        let digitos = somente_digitos(numero, 9);
165        let part1 = digitos[0..8].to_vec();
166        let dv1 = &digitos[8];
167        let digitos_verificadores = calc_digito(part1, multiplicadores1, onze_menos_mod11);
168        digitos_verificadores == *dv1
169    }
170
171    fn validar(&self) -> bool {
172        Self::is_valid(self.0)
173    }
174}
175
176impl Validador for Cns<'_> {
177    fn is_valid(numero: &str) -> bool {
178        fn valida_1_2(numero: &str) -> bool {
179            let multiplicadores1 = vec![15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5];
180            let mut digitos = somente_digitos(numero, 15);
181            let dv = digitos.split_off(11);
182            let mut soma = calc_digito(digitos, multiplicadores1, |x| x);
183            let resto = soma % 11;
184            let calculo = 11 - resto;
185            let mut digito_anterior = 0;
186            let calculo = if calculo == 11 {
187                0
188            } else if calculo == 10 {
189                soma += 2;
190                let resto = soma % 11;
191                digito_anterior += 1;
192                11 - resto
193            } else {
194                calculo
195            };
196            println!("{:?}", calculo);
197
198            //retorno
199            dv == vec![0, 0, digito_anterior, calculo]
200        }
201        fn valida_7_8_9(numero: &str) -> bool {
202            let multiplicadores1 = vec![15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
203            let mut digitos = somente_digitos(numero, 15);
204
205            completa_esquerda(&mut digitos, 15);
206            let calculo = calc_digito(digitos, multiplicadores1, |x| x % 11);
207            calculo == 0
208        }
209
210        let primeiro_digito = somente_digitos(numero, 1);
211        match primeiro_digito.first() {
212            Some(1) | Some(2) => valida_1_2(numero),
213            Some(7) | Some(8) | Some(9) => valida_7_8_9(numero),
214            _ => false,
215        }
216    }
217
218    fn validar(&self) -> bool {
219        Self::is_valid(self.0)
220    }
221}
222
223/// Se for número provisório usa o número do Pis
224impl Validador for TipoCns<'_> {
225    fn validar(&self) -> bool {
226        match self {
227            TipoCns::Cns(value) => value.validar(),
228            TipoCns::Provisorio(value) => value.validar(),
229        }
230    }
231}
232
233impl Validador for CodigoBarrasGs1<'_> {
234    fn is_valid(numero: &str) -> bool {
235        let multiplicadores1 = vec![3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3];
236        let mut digitos = somente_digitos(numero, 18);
237        completa_esquerda(&mut digitos, 18);
238        let dv1 = &digitos.split_off(17);
239        let digitos_verificadores =
240            calc_digito(digitos, multiplicadores1, |x| (x / 10 + 1) * 10 - x);
241        digitos_verificadores == dv1[0]
242    }
243
244    fn validar(&self) -> bool {
245        Self::is_valid(self.0)
246    }
247}
248
249impl Validador for Pis<'_> {
250    fn is_valid(numero: &str) -> bool {
251        let multiplicadores1 = vec![3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
252        let mut digitos = somente_digitos(numero, 11);
253        let dv1 = digitos.split_off(10);
254
255        dv1[0] == calc_digito(digitos, multiplicadores1, onze_menos_mod11)
256    }
257
258    fn validar(&self) -> bool {
259        Self::is_valid(self.0)
260    }
261}