Skip to content

Commit

Permalink
Reduce the use of .unwrap()
Browse files Browse the repository at this point in the history
Signed-off-by: JmPotato <[email protected]>
  • Loading branch information
JmPotato committed Aug 25, 2024
1 parent 8cdb60a commit 5201f35
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 46 deletions.
24 changes: 9 additions & 15 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,34 +51,30 @@ impl AppState {

info!("connecting to the database");
// connect to the database.
let db = match sqlx::MySqlPool::connect(&config.mysql_connection_url()).await {
Ok(db) => db,
Err(e) => return Err(Error::Sqlx(e)),
};
let db = sqlx::MySqlPool::connect(&config.mysql_connection_url()?).await?;
info!("initializing the database");
// create the tables if they don't exist.
create_tables(&db).await.unwrap();
create_tables(&db).await?;
// init the admin user.
let admin_username = config.admin_username();
User::insert(
&db,
&admin_username,
&password_auth::generate_hash(&admin_username),
)
.await
.unwrap();
.await?;

info!("initializing the environment");
let mut env = Environment::new();
// iterate the templates directory and add all the templates.
for entry in std::fs::read_dir(TEMPLATES_DIR).unwrap() {
for entry in std::fs::read_dir(TEMPLATES_DIR)? {
let path = entry.unwrap().path();
if !path.is_file() {
continue;
}
let file_name = path.file_name().unwrap().to_string_lossy().into_owned();
let template_content = std::fs::read_to_string(path).unwrap();
env.add_template_owned(file_name, template_content).unwrap();
let template_content = std::fs::read_to_string(path)?;
env.add_template_owned(file_name, template_content)?;
}
// load the global variables into the environment.
env.add_global("config", Value::from_object(config.clone()));
Expand Down Expand Up @@ -205,11 +201,9 @@ impl App {
)
.with_state(Arc::new(self.state.clone()));

let listener = tokio::net::TcpListener::bind(self.state.config.server_url())
.await
.unwrap();
info!("listening on {}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
let listener = tokio::net::TcpListener::bind(self.state.config.server_url()).await?;
info!("listening on {}", listener.local_addr()?);
axum::serve(listener, app).await?;

Ok(())
}
Expand Down
35 changes: 24 additions & 11 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ pub struct Config {

impl Config {
pub fn new(path: &str) -> Result<Self, Error> {
let config_content = std::fs::read_to_string(path).unwrap();
let config_content = std::fs::read_to_string(path)?;
let mut config: Self = toml::from_str(&config_content).map_err(Error::Toml)?;
// get some environment variables.
config.load_env_vars()?;
Expand Down Expand Up @@ -201,18 +201,31 @@ impl Config {

// get the MySQL connection URL according to the config, it will use `connection_url` if it is set,
// otherwise it will use `username`, `password`, `host`, `port` and `database` to build one.
pub fn mysql_connection_url(&self) -> String {
if let Some(connection_url) = self.mysql.connection_url.clone() {
connection_url
pub fn mysql_connection_url(&self) -> Result<String, Error> {
if let Some(connection_url) = &self.mysql.connection_url {
Ok(connection_url.clone())
} else {
format!(
let (username, password, host, port, database) = (
self.mysql
.username
.as_ref()
.ok_or(Error::InvalidMySQLConfig)?,
self.mysql
.password
.as_ref()
.ok_or(Error::InvalidMySQLConfig)?,
self.mysql.host.as_ref().ok_or(Error::InvalidMySQLConfig)?,
self.mysql.port.ok_or(Error::InvalidMySQLConfig)?,
self.mysql
.database
.as_ref()
.ok_or(Error::InvalidMySQLConfig)?,
);

Ok(format!(
"mysql://{}:{}@{}:{}/{}",
self.mysql.username.as_ref().unwrap(),
self.mysql.password.as_ref().unwrap(),
self.mysql.host.as_ref().unwrap(),
self.mysql.port.unwrap(),
self.mysql.database.as_ref().unwrap()
)
username, password, host, port, database
))
}
}

Expand Down
13 changes: 11 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,21 @@ pub enum Error {
#[error(transparent)]
Toml(#[from] toml::de::Error),

#[error("config validation failed: {0}")]
ConfigValidation(String),
#[error(transparent)]
Io(#[from] std::io::Error),

#[error(transparent)]
MiniJinja(#[from] minijinja::Error),

#[error(transparent)]
Sqlx(#[from] sqlx::Error),

#[error(transparent)]
TaskJoin(#[from] task::JoinError),

#[error("config validation failed: {0}")]
ConfigValidation(String),

#[error("invalid MySQL config, please specify the connection URL or the username, password, host, port and database")]
InvalidMySQLConfig,
}
22 changes: 16 additions & 6 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,27 +504,37 @@ pub async fn handler_delete_article(
Path(editor_path): Path<EditorPath>,
) -> impl IntoResponse {
let redirect = Redirect::to("/admin");
match Article::delete(&state.db, editor_path.id.unwrap()).await {
Ok(_) => redirect.into_response(),
let id = match editor_path.id {
Some(id) => id,
None => return redirect.into_response(),
};
match Article::delete(&state.db, id).await {
Ok(_) => redirect,
Err(err) => {
error!("failed deleting article: {:?}", err);
redirect.into_response()
redirect
}
}
.into_response()
}

pub async fn handler_delete_page(
state: State<Arc<AppState>>,
Path(editor_path): Path<EditorPath>,
) -> impl IntoResponse {
let redirect = Redirect::to("/admin");
match Page::delete(&state.db, editor_path.id.unwrap()).await {
Ok(_) => redirect.into_response(),
let id = match editor_path.id {
Some(id) => id,
None => return redirect.into_response(),
};
match Page::delete(&state.db, id).await {
Ok(_) => redirect,
Err(err) => {
error!("failed deleting page: {:?}", err);
redirect.into_response()
redirect
}
}
.into_response()
}

pub async fn handler_ping() -> impl IntoResponse {
Expand Down
20 changes: 10 additions & 10 deletions src/models/articles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Article {
sqlx::query_as("SELECT * FROM articles ORDER BY id DESC")
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_on_page(db: &sqlx::MySqlPool, page: u32, article_per_page: u32) -> Vec<Self> {
Expand All @@ -27,14 +27,14 @@ impl Article {
.bind((page - 1) * article_per_page)
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_total_count(db: &sqlx::MySqlPool) -> i32 {
sqlx::query_scalar("SELECT COUNT(*) FROM articles")
.fetch_one(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_by_id(db: &sqlx::MySqlPool, id: i32) -> Option<Self> {
Expand All @@ -47,23 +47,23 @@ impl Article {

pub async fn get_by_tag(db: &sqlx::MySqlPool, tag: &str) -> Vec<Self> {
sqlx::query_as(
"SELECT a.id, a.title, a.content, a.tags, a.created_at, a.updated_at
FROM articles AS a
INNER JOIN tags AS t ON a.id = t.article_id
WHERE t.name = ?
"SELECT a.id, a.title, a.content, a.tags, a.created_at, a.updated_at
FROM articles AS a
INNER JOIN tags AS t ON a.id = t.article_id
WHERE t.name = ?
ORDER BY a.id DESC",
)
.bind(tag)
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_latest_updated(db: &sqlx::MySqlPool) -> Option<DateTime<Utc>> {
sqlx::query_scalar("SELECT MAX(updated_at) FROM articles")
.fetch_one(db)
.await
.unwrap()
.ok()
}

pub async fn insert(
Expand Down Expand Up @@ -185,6 +185,6 @@ impl Tags {
sqlx::query_as("SELECT name, COUNT(name) AS num FROM tags GROUP BY name ORDER BY num DESC")
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}
}
4 changes: 2 additions & 2 deletions src/models/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ impl Page {
sqlx::query_as("SELECT * FROM pages ORDER BY id DESC")
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_all_titles(db: &sqlx::MySqlPool) -> Vec<String> {
sqlx::query_scalar("SELECT title FROM pages ORDER BY title ASC")
.fetch_all(db)
.await
.unwrap()
.unwrap_or_default()
}

pub async fn get_by_id(db: &sqlx::MySqlPool, id: i32) -> Option<Self> {
Expand Down

0 comments on commit 5201f35

Please sign in to comment.