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 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
223impl 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}