I just started learning RUST, and try to implement in a pet project function like Django's [get_or_create](https://docs.djangoproject.com/en/4.1/ref/models/querysets/#get-or-create).
Now my implementation looks too verbose, I hope that rust can be more neat.
Therefore, how can I implement this function in less verbose way?
Probable there is a way to shorten nested **match** constructions below?
``` lang-rs
use log::warn;
use diesel::prelude::*;
use diesel::result;
use crate::db::{get_connection, PgPool};
use crate::models::{NewUser, User};
pub fn get_or_create_user(pool: &PgPool, email: &str) -> User {
use crate::schema::users;
let new_user = NewUser { email };
let mut conn = get_connection(pool);
let result = diesel::insert_into(users::table)
.values(&new_user)
.get_result(&mut conn);
match result {
Ok(user) => return user,
Err(err) => match err {
result::Error::DatabaseError(err_kind, info) => match err_kind {
result::DatabaseErrorKind::UniqueViolation => {
warn!(
"{:?} is already exists. Info: {:?}. Skipping.",
new_user, info
);
// another query to DB to get existing user by email
let user = user_by_email(pool, new_user.email);
return user;
}
_ => {
panic!("Database error: {:?}", info);
}
},
_ => {
// TODO: decide how to deal with unexpected errors
return User {
id: 0,
email: "".into(),
};
}
},
}
}
pub fn user_by_email(pool: &PgPool, user_email: &str) -> User {
use crate::schema::users::dsl::*;
let mut conn = get_connection(pool);
let user = crate::schema::users::dsl::users
.filter(email.eq(user_email))
.first(&mut conn)
.unwrap();
return user;
}
```