feat: implement main application structure with UI and layout management
- Added main application logic in `src/ui/app.rs` to handle state and modal dialogs. - Created module structure for UI components in `src/ui/mod.rs`. - Implemented column configuration screen in `src/ui/screens/configuracao_colunas.rs`. - Developed file import screen in `src/ui/screens/import.rs` for CSV and XLSX files. - Added layout management screen in `src/ui/screens/layouts.rs` for saving and importing layouts. - Created result display screen in `src/ui/screens/resultado.rs` to show analysis results. - Introduced modular organization for screens in `src/ui/screens/mod.rs`.
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum ErroNumero {
|
||||
#[error("Número zero não é válido para uma nota fiscal")]
|
||||
Zero,
|
||||
#[error("Valor não numérico: '{0}'")]
|
||||
NaoNumerico(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum ErroSerie {
|
||||
#[error("Série inválida: '{0}' (deve conter de 1 a 3 dígitos numéricos)")]
|
||||
Invalida(String),
|
||||
#[error("Série vazia")]
|
||||
Vazia,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum ErroValor {
|
||||
#[error("Valor negativo não é permitido: '{0}'")]
|
||||
Negativo(String),
|
||||
#[error("Valor não numérico: '{0}'")]
|
||||
NaoNumerico(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum ErroLayout {
|
||||
#[error("Campo obrigatório ausente: '{0}'")]
|
||||
CampoObrigatorioAusente(String),
|
||||
#[error("JSON malformado: {0}")]
|
||||
JsonMalformado(String),
|
||||
#[error("Conflito de nome: layout '{0}' já existe")]
|
||||
NomeConflitante(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone)]
|
||||
pub enum ErroArquivo {
|
||||
#[error("Arquivo muito grande ({0} bytes). Limite: 50 MB")]
|
||||
TamanhoExcedido(u64),
|
||||
#[error("Arquivo corrompido ou ilegível: {0}")]
|
||||
Corrompido(String),
|
||||
#[error("Formato não suportado: {0}")]
|
||||
FormatoNaoSuportado(String),
|
||||
#[error("Erro de leitura: {0}")]
|
||||
ErroLeitura(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ErroAnalise {
|
||||
#[error("Intervalo de faltantes muito grande para a série '{serie}': {intervalo} registros")]
|
||||
IntervaloMuitoGrande { serie: String, intervalo: u64 },
|
||||
#[error("Campo obrigatório não mapeado: {0}")]
|
||||
CampoObrigatorioNaoMapeado(String),
|
||||
#[error("Índice de coluna inválido: campo '{campo}', índice {indice}")]
|
||||
IndiceInvalido { campo: String, indice: usize },
|
||||
#[error("Dois campos mapeados para o mesmo índice: {0}")]
|
||||
IndicesDuplicados(String),
|
||||
}
|
||||
|
||||
/// Aviso coletado durante a importação, para ser exibido de forma consolidada ao usuário.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AvisoImportacao {
|
||||
pub categoria: CategoriaAviso,
|
||||
pub mensagem: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum CategoriaAviso {
|
||||
LinhaMalformada,
|
||||
NumeroInvalido,
|
||||
SerieInvalida,
|
||||
ValorInvalido,
|
||||
RegistroDescartado,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CategoriaAviso {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
CategoriaAviso::LinhaMalformada => write!(f, "Linhas malformadas"),
|
||||
CategoriaAviso::NumeroInvalido => write!(f, "Valores de Numero inválidos"),
|
||||
CategoriaAviso::SerieInvalida => write!(f, "Registros com Série inválida"),
|
||||
CategoriaAviso::ValorInvalido => write!(f, "Valores monetários inválidos"),
|
||||
CategoriaAviso::RegistroDescartado => write!(f, "Registros descartados"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resumo consolidado de avisos para exibição em um único modal.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ResumoAvisos {
|
||||
pub linhas_malformadas: usize,
|
||||
pub numeros_invalidos: usize,
|
||||
pub series_invalidas: usize,
|
||||
pub valores_invalidos: usize,
|
||||
pub detalhes: Vec<String>,
|
||||
}
|
||||
|
||||
impl ResumoAvisos {
|
||||
pub fn tem_avisos(&self) -> bool {
|
||||
self.linhas_malformadas > 0
|
||||
|| self.numeros_invalidos > 0
|
||||
|| self.series_invalidas > 0
|
||||
|| self.valores_invalidos > 0
|
||||
}
|
||||
|
||||
pub fn linhas_para_exibir(&self) -> Vec<String> {
|
||||
let mut linhas = Vec::new();
|
||||
if self.linhas_malformadas > 0 {
|
||||
linhas.push(format!(
|
||||
"{} linhas descartadas por malformação",
|
||||
self.linhas_malformadas
|
||||
));
|
||||
}
|
||||
if self.numeros_invalidos > 0 {
|
||||
linhas.push(format!(
|
||||
"{} valores de Numero inválidos convertidos ou descartados",
|
||||
self.numeros_invalidos
|
||||
));
|
||||
}
|
||||
if self.series_invalidas > 0 {
|
||||
linhas.push(format!(
|
||||
"{} registros com Série inválida descartados",
|
||||
self.series_invalidas
|
||||
));
|
||||
}
|
||||
if self.valores_invalidos > 0 {
|
||||
linhas.push(format!(
|
||||
"{} valores monetários inválidos descartados",
|
||||
self.valores_invalidos
|
||||
));
|
||||
}
|
||||
linhas.extend(self.detalhes.clone());
|
||||
linhas
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user