début gestion des erreurs
This commit is contained in:
20
src/app.rs
20
src/app.rs
@@ -16,6 +16,8 @@ pub struct App {
|
|||||||
pub tr_types: Vec<TransactionType>,
|
pub tr_types: Vec<TransactionType>,
|
||||||
pub selected_tab: usize,
|
pub selected_tab: usize,
|
||||||
pub tabs: Vec<String>,
|
pub tabs: Vec<String>,
|
||||||
|
pub error: String,
|
||||||
|
pub error_showing: bool,
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +52,20 @@ impl App {
|
|||||||
"Chart 3".to_string(),
|
"Chart 3".to_string(),
|
||||||
]
|
]
|
||||||
.to_vec(),
|
.to_vec(),
|
||||||
|
error: String::new(),
|
||||||
|
error_showing: false,
|
||||||
connection: con,
|
connection: con,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_list_accounts(&mut self) -> Vec<Account> {
|
pub fn get_list_accounts(&mut self) -> Vec<Account> {
|
||||||
return self.acc_list.get_accounts(&self.connection);
|
return match self.acc_list.get_accounts(&self.connection) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(e) => {
|
||||||
|
self.error = e.to_string();
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_ac(&mut self) {
|
pub fn next_ac(&mut self) {
|
||||||
@@ -82,7 +92,13 @@ impl App {
|
|||||||
pub fn save_new_account(&mut self) {
|
pub fn save_new_account(&mut self) {
|
||||||
let new = self.new_account.get_id() == 0;
|
let new = self.new_account.get_id() == 0;
|
||||||
self.next_ac_input();
|
self.next_ac_input();
|
||||||
let ac = data_layer::upsert_account(&self.connection, self.new_account.clone());
|
let ac = match data_layer::upsert_account(&self.connection, self.new_account.clone()) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(e) => {
|
||||||
|
self.error = e.to_string();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
if new {
|
if new {
|
||||||
self.acc_list.add_account(ac);
|
self.acc_list.add_account(ac);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ pub fn setup(con: &Connection) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upsert_account(con: &Connection, ac: Account) -> Account {
|
pub fn upsert_account(
|
||||||
|
con: &Connection,
|
||||||
|
ac: Account,
|
||||||
|
) -> Result<Account, Box<dyn std::error::Error>> {
|
||||||
let query;
|
let query;
|
||||||
let ac_type = ac.get_ac_type() as i64;
|
let ac_type = ac.get_ac_type() as i64;
|
||||||
if ac.get_id() == 0 {
|
if ac.get_id() == 0 {
|
||||||
@@ -50,30 +53,33 @@ pub fn upsert_account(con: &Connection, ac: Account) -> Account {
|
|||||||
query = "UPDATE Accounts SET name = :name, type = :type, asset_price = :asset_price WHERE id = :id RETURNING id;";
|
query = "UPDATE Accounts SET name = :name, type = :type, asset_price = :asset_price WHERE id = :id RETURNING id;";
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut statement = con.prepare(query).unwrap();
|
let mut statement = con
|
||||||
statement.bind((":name", &ac.get_name() as &str)).unwrap();
|
.prepare(query)
|
||||||
statement.bind((":type", ac_type)).unwrap();
|
.map_err(|e| format!("Could not prepare query: {}", e))?;
|
||||||
statement
|
statement.bind((":name", &ac.get_name() as &str))?;
|
||||||
.bind((":asset_price", ac.get_asset_price()))
|
statement.bind((":type", ac_type))?;
|
||||||
.unwrap();
|
statement.bind((":asset_price", ac.get_asset_price()))?;
|
||||||
|
|
||||||
if ac.get_id() != 0 {
|
if ac.get_id() != 0 {
|
||||||
statement.bind((":id", ac.get_id())).unwrap();
|
statement.bind((":id", ac.get_id()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id;
|
let id;
|
||||||
if let Ok(State::Row) = statement.next() {
|
if let Ok(State::Row) = statement.next() {
|
||||||
id = statement.read::<i64, _>("id").unwrap();
|
id = statement.read::<i64, _>("id")?;
|
||||||
} else {
|
} else {
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Account::new(
|
let ac_type_enum =
|
||||||
|
AccountType::try_from(ac_type).map_err(|_| "Could not parse account type")?;
|
||||||
|
|
||||||
|
return Ok(Account::new(
|
||||||
id,
|
id,
|
||||||
ac.get_name(),
|
ac.get_name(),
|
||||||
ac.get_asset_price(),
|
ac.get_asset_price(),
|
||||||
ac_type.try_into().unwrap(),
|
ac_type_enum,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn get_account(con: &Connection, id: i64) -> Account {
|
// pub fn get_account(con: &Connection, id: i64) -> Account {
|
||||||
@@ -126,27 +132,28 @@ JOIN Accounts a ON t.account_id = a.id"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_accounts(con: &Connection) -> Vec<Account> {
|
pub fn get_accounts(con: &Connection) -> Result<Vec<Account>, Box<dyn std::error::Error>> {
|
||||||
let query = "SELECT * FROM Accounts";
|
let query = "SELECT * FROM Accounts";
|
||||||
let mut statement = con.prepare(query).unwrap();
|
let mut statement = con
|
||||||
|
.prepare(query)
|
||||||
|
.map_err(|e| format!("Could not prepare query: {}", e))?;
|
||||||
let mut vec = Vec::<Account>::new();
|
let mut vec = Vec::<Account>::new();
|
||||||
|
|
||||||
vec.push(Account::new(0, "All".to_string(), 0.0, AccountType::Cash));
|
vec.push(Account::new(0, "All".to_string(), 0.0, AccountType::Cash));
|
||||||
|
|
||||||
while let Ok(State::Row) = statement.next() {
|
while let Ok(State::Row) = statement.next() {
|
||||||
|
let type_i = statement.read::<i64, _>("type")?;
|
||||||
|
let ac_type_enum =
|
||||||
|
AccountType::try_from(type_i).map_err(|_| "Could not parse account type")?;
|
||||||
vec.push(Account::new(
|
vec.push(Account::new(
|
||||||
statement.read::<i64, _>("id").unwrap(),
|
statement.read::<i64, _>("id")?,
|
||||||
statement.read::<String, _>("name").unwrap(),
|
statement.read::<String, _>("name")?,
|
||||||
statement.read::<f64, _>("asset_price").unwrap(),
|
statement.read::<f64, _>("asset_price")?,
|
||||||
statement
|
ac_type_enum,
|
||||||
.read::<i64, _>("type")
|
|
||||||
.unwrap()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec;
|
return Ok(vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn upsert_transaction_type(con: &Connection, tt: TransactionType) -> TransactionType {
|
// pub fn upsert_transaction_type(con: &Connection, tt: TransactionType) -> TransactionType {
|
||||||
|
|||||||
@@ -17,11 +17,14 @@ impl AccountList {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_accounts(&mut self, con: &Connection) -> Vec<Account> {
|
pub fn get_accounts(
|
||||||
|
&mut self,
|
||||||
|
con: &Connection,
|
||||||
|
) -> Result<Vec<Account>, Box<dyn std::error::Error>> {
|
||||||
if self.accounts.iter().count() == 0 {
|
if self.accounts.iter().count() == 0 {
|
||||||
self.accounts = data_layer::get_accounts(con);
|
self.accounts = data_layer::get_accounts(con)?;
|
||||||
}
|
}
|
||||||
return self.accounts.clone();
|
return Ok(self.accounts.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_selected_id(&self) -> i64 {
|
pub fn get_selected_id(&self) -> i64 {
|
||||||
|
|||||||
@@ -63,6 +63,13 @@ where
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let KeyCode::Enter = key.code
|
||||||
|
&& app.error_showing
|
||||||
|
{
|
||||||
|
app.error = String::new();
|
||||||
|
app.error_showing = false;
|
||||||
|
}
|
||||||
|
|
||||||
match app.current_screen {
|
match app.current_screen {
|
||||||
CurrentScreen::Main => match key.code {
|
CurrentScreen::Main => match key.code {
|
||||||
KeyCode::Char('q') => {
|
KeyCode::Char('q') => {
|
||||||
|
|||||||
18
src/ui.rs
18
src/ui.rs
@@ -299,6 +299,24 @@ pub fn ui(frame: &mut Frame, app: &mut App) {
|
|||||||
frame.render_widget(Clear, area);
|
frame.render_widget(Clear, area);
|
||||||
frame.render_widget(exit_paragraph, area);
|
frame.render_widget(exit_paragraph, area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !app.error.is_empty() {
|
||||||
|
app.error_showing = true;
|
||||||
|
let popup = Block::default()
|
||||||
|
.title("Error")
|
||||||
|
.borders(Borders::all())
|
||||||
|
.style(Style::default());
|
||||||
|
|
||||||
|
let error_text = Text::styled(&app.error, Style::default().fg(Color::Red));
|
||||||
|
|
||||||
|
let error_paragraph = Paragraph::new(error_text)
|
||||||
|
.block(popup)
|
||||||
|
.wrap(Wrap { trim: false });
|
||||||
|
|
||||||
|
let area = centered_rect(50, 20, frame.area());
|
||||||
|
frame.render_widget(Clear, area);
|
||||||
|
frame.render_widget(error_paragraph, area);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
|
||||||
|
|||||||
Reference in New Issue
Block a user