Skip to content

Commit

Permalink
remove lazy_static (#941)
Browse files Browse the repository at this point in the history
* remove lazy_static
  • Loading branch information
jondot authored Oct 31, 2024
1 parent e748f55 commit 8ce70ea
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 177 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ async-trait = { workspace = true }
axum = { workspace = true }
axum-extra = { version = "0.9", features = ["cookie"] }
regex = { workspace = true }
lazy_static = { workspace = true }
fs-err = "2.11.0"
# mailer
tera = "1.19.1"
Expand Down Expand Up @@ -143,7 +142,6 @@ regex = "1"
thiserror = "1"
serde = "1"
serde_json = "1"
lazy_static = "1.4.0"
async-trait = { version = "0.1.74" }
axum = { version = "0.7.5", features = ["macros"] }
tower = "0.4"
Expand Down
2 changes: 0 additions & 2 deletions examples/demo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions examples/demo/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ impl Hooks for App {
}

// <snip id="app-initializers">
async fn initializers(ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let mut initializers: Vec<Box<dyn Initializer>> = vec![
async fn initializers(_ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {
let initializers: Vec<Box<dyn Initializer>> = vec![
Box::new(initializers::axum_session::AxumSessionInitializer),
Box::new(initializers::view_engine::ViewEngineInitializer),
Box::new(initializers::hello_view_engine::HelloViewEngineInitializer),
Expand Down
9 changes: 4 additions & 5 deletions examples/demo/tests/requests/notes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use insta::{assert_debug_snapshot, with_settings};
use loco_rs::testing;
use rstest::rstest;
use sea_orm::entity::prelude::*;
use serde_json;
use serial_test::serial;

// TODO: see how to dedup / extract this to app-local test utils
Expand Down Expand Up @@ -34,7 +33,7 @@ async fn can_get_notes(#[case] test_name: &str, #[case] params: serde_json::Valu

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand Down Expand Up @@ -62,7 +61,7 @@ async fn can_add_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand All @@ -87,7 +86,7 @@ async fn can_get_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand All @@ -113,7 +112,7 @@ async fn can_delete_note() {

with_settings!({
filters => {
let mut combined_filters = testing::CLEANUP_DATE.to_vec();
let mut combined_filters = testing::get_cleanup_date().clone();
combined_filters.extend(vec![(r#"\"id\\":\d+"#, r#""id\":ID"#)]);
combined_filters
}
Expand Down
1 change: 0 additions & 1 deletion loco-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ path = "src/lib.rs"

[dependencies]

lazy_static = { workspace = true }
rrgen = "0.5.3"
serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
11 changes: 6 additions & 5 deletions loco-gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// TODO: should be more properly aligned with extracting out the db-related gen
// code and then feature toggling it
#![allow(dead_code)]
use lazy_static::lazy_static;
use rrgen::{GenResult, RRgen};
use serde::{Deserialize, Serialize};
use serde_json::json;
Expand All @@ -14,7 +13,7 @@ mod model;
mod scaffold;
#[cfg(test)]
mod testutil;
use std::str::FromStr;
use std::{str::FromStr, sync::OnceLock};

const CONTROLLER_T: &str = include_str!("templates/controller.t");
const CONTROLLER_TEST_T: &str = include_str!("templates/request_test.t");
Expand Down Expand Up @@ -109,11 +108,13 @@ impl Mappings {
}
}

lazy_static! {
static ref MAPPINGS: Mappings = {
static MAPPINGS: OnceLock<Mappings> = OnceLock::new();

fn get_mappings() -> &'static Mappings {
MAPPINGS.get_or_init(|| {
let json_data = include_str!("./mappings.json");
serde_json::from_str(json_data).expect("JSON was not well-formatted")
};
})
}

#[derive(clap::ValueEnum, Clone, Debug)]
Expand Down
8 changes: 5 additions & 3 deletions loco-gen/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ use rrgen::RRgen;
use serde_json::json;

use super::{Error, Result};
use crate::get_mappings;

const MODEL_T: &str = include_str!("templates/model.t");
const MODEL_TEST_T: &str = include_str!("templates/model_test.t");

use super::{collect_messages, AppInfo, MAPPINGS};
use super::{collect_messages, AppInfo};

/// skipping some fields from the generated models.
/// For example, the `created_at` and `updated_at` fields are automatically
Expand Down Expand Up @@ -44,11 +45,12 @@ pub fn generate(
// user, user_id
references.push((fname, fkey));
} else {
let schema_type = MAPPINGS.schema_field(ftype.as_str()).ok_or_else(|| {
let mappings = get_mappings();
let schema_type = mappings.schema_field(ftype.as_str()).ok_or_else(|| {
Error::Message(format!(
"type: {} not found. try any of: {:?}",
ftype,
MAPPINGS.schema_fields()
mappings.schema_fields()
))
})?;
columns.push((fname.to_string(), schema_type.as_str()));
Expand Down
9 changes: 5 additions & 4 deletions loco-gen/src/scaffold.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rrgen::RRgen;
use serde_json::json;

use crate as gen;
use crate::{self as gen, get_mappings};

const API_CONTROLLER_SCAFFOLD_T: &str = include_str!("templates/scaffold/api/controller.t");
const API_CONTROLLER_TEST_T: &str = include_str!("templates/scaffold/api/test.t");
Expand All @@ -22,7 +22,7 @@ const HTML_VIEW_CREATE_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/
const HTML_VIEW_SHOW_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/view_show.t");
const HTML_VIEW_LIST_SCAFFOLD_T: &str = include_str!("templates/scaffold/html/view_list.t");

use super::{collect_messages, model, AppInfo, Error, Result, MAPPINGS};
use super::{collect_messages, model, AppInfo, Error, Result};

pub fn generate(
rrgen: &RRgen,
Expand All @@ -35,6 +35,7 @@ pub fn generate(
// - never run with migration_only, because the controllers will refer to the
// models. the models only arrive after migration and entities sync.
let model_messages = model::generate(rrgen, name, false, false, fields, appinfo)?;
let mappings = get_mappings();

let mut columns = Vec::new();
for (fname, ftype) in fields {
Expand All @@ -46,11 +47,11 @@ pub fn generate(
continue;
}
if ftype != "references" {
let schema_type = MAPPINGS.rust_field(ftype.as_str()).ok_or_else(|| {
let schema_type = mappings.rust_field(ftype.as_str()).ok_or_else(|| {
Error::Message(format!(
"type: {} not found. try any of: {:?}",
ftype,
MAPPINGS.rust_fields()
mappings.rust_fields()
))
})?;
columns.push((fname.to_string(), schema_type.as_str(), ftype));
Expand Down
11 changes: 6 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,21 @@ Notes:
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
sync::OnceLock,
};

use fs_err as fs;
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
use serde_json::json;
use tracing::info;

use crate::{controller::middleware, environment::Environment, logger, scheduler, Error, Result};

lazy_static! {
static ref DEFAULT_FOLDER: PathBuf = PathBuf::from("config");
}
static DEFAULT_FOLDER: OnceLock<PathBuf> = OnceLock::new();

fn get_default_folder() -> &'static PathBuf {
DEFAULT_FOLDER.get_or_init(|| PathBuf::from("config"))
}
/// Main application configuration structure.
///
/// This struct encapsulates various configuration settings. The configuration
Expand Down Expand Up @@ -496,7 +497,7 @@ impl Config {
/// Config::new(environment).expect("configuration loading")
/// }
pub fn new(env: &Environment) -> Result<Self> {
let config = Self::from_folder(env, DEFAULT_FOLDER.as_path())?;
let config = Self::from_folder(env, get_default_folder().as_path())?;
Ok(config)
}

Expand Down
11 changes: 6 additions & 5 deletions src/controller/app_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
//! configuring routes in an Axum application. It allows you to define route
//! prefixes, add routes, and configure middlewares for the application.

use std::fmt;
use std::{fmt, sync::OnceLock};

use axum::Router as AXRouter;
use lazy_static::lazy_static;
use regex::Regex;

#[cfg(feature = "channels")]
Expand All @@ -16,8 +15,10 @@ use crate::{
Result,
};

lazy_static! {
static ref NORMALIZE_URL: Regex = Regex::new(r"/+").unwrap();
static NORMALIZE_URL: OnceLock<Regex> = OnceLock::new();

fn get_normalize_url() -> &'static Regex {
NORMALIZE_URL.get_or_init(|| Regex::new(r"/+").unwrap())
}

/// Represents the routes of the application.
Expand Down Expand Up @@ -91,7 +92,7 @@ impl AppRoutes {
parts.push(handler.uri.to_string());
let joined_parts = parts.join("/");

let normalized = NORMALIZE_URL.replace_all(&joined_parts, "/");
let normalized = get_normalize_url().replace_all(&joined_parts, "/");
let uri = if normalized == "/" {
normalized.to_string()
} else {
Expand Down
91 changes: 57 additions & 34 deletions src/controller/backtrace.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,67 @@
use lazy_static::lazy_static;
use std::sync::OnceLock;

use regex::Regex;

use crate::{Error, Result};

lazy_static! {
static ref NAME_BLOCKLIST: Vec<Regex> = [
"^___rust_try",
"^__pthread",
"^__clone",
"^<loco_rs::errors::Error as",
"^loco_rs::errors::Error::bt",
/*
"^<?tokio",
"^<?future",
"^<?tower",
"^<?futures",
"^<?hyper",
"^<?axum",
"<F as futures_core",
"^<F as axum::",
"^<?std::panic",
"^<?core::",
"^rust_panic",
"^rayon",
"^rust_begin_unwind",
"^start_thread",
"^call_once",
"^catch_unwind",
*/
]
.iter()
.map(|s| Regex::new(s).unwrap())
.collect::<Vec<_>>();
static ref FILE_BLOCKLIST: Vec<Regex> = ["axum-.*$", "tower-.*$", "hyper-.*$", "tokio-.*$", "futures-.*$", "^/rustc"]
static NAME_BLOCKLIST: OnceLock<Vec<Regex>> = OnceLock::new();
static FILE_BLOCKLIST: OnceLock<Vec<Regex>> = OnceLock::new();

fn get_name_blocklist() -> &'static Vec<Regex> {
NAME_BLOCKLIST.get_or_init(|| {
[
"^___rust_try",
"^__pthread",
"^__clone",
"^<loco_rs::errors::Error as",
"^loco_rs::errors::Error::bt",
/*
"^<?tokio",
"^<?future",
"^<?tower",
"^<?futures",
"^<?hyper",
"^<?axum",
"<F as futures_core",
"^<F as axum::",
"^<?std::panic",
"^<?core::",
"^rust_panic",
"^rayon",
"^rust_begin_unwind",
"^start_thread",
"^call_once",
"^catch_unwind",
*/
]
.iter()
.map(|s| Regex::new(s).unwrap())
.collect::<Vec<_>>()
})
}

fn get_file_blocklist() -> &'static Vec<Regex> {
FILE_BLOCKLIST.get_or_init(|| {
[
"axum-.*$",
"tower-.*$",
"hyper-.*$",
"tokio-.*$",
"futures-.*$",
"^/rustc",
]
.iter()
.map(|s| Regex::new(s).unwrap())
.collect::<Vec<_>>();
.collect::<Vec<_>>()
})
}

pub fn print_backtrace(bt: &std::backtrace::Backtrace) -> Result<()> {
backtrace_printer::print_backtrace(&mut std::io::stdout(), bt, &NAME_BLOCKLIST, &FILE_BLOCKLIST)
.map_err(Error::msg)
backtrace_printer::print_backtrace(
&mut std::io::stdout(),
bt,
get_name_blocklist(),
get_file_blocklist(),
)
.map_err(Error::msg)
}
11 changes: 7 additions & 4 deletions src/controller/describe.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::sync::OnceLock;

use axum::{http, routing::MethodRouter};
use lazy_static::lazy_static;
use regex::Regex;

use crate::app::AppContext;

lazy_static! {
static ref DESCRIBE_METHOD_ACTION: Regex = Regex::new(r"\b(\w+):\s*BoxedHandler\b").unwrap();
static DESCRIBE_METHOD_ACTION: OnceLock<Regex> = OnceLock::new();

fn get_describe_method_action() -> &'static Regex {
DESCRIBE_METHOD_ACTION.get_or_init(|| Regex::new(r"\b(\w+):\s*BoxedHandler\b").unwrap())
}

/// Extract the allow list method actions from [`MethodRouter`].
Expand All @@ -16,7 +19,7 @@ lazy_static! {
pub fn method_action(method: &MethodRouter<AppContext>) -> Vec<http::Method> {
let method_str = format!("{method:?}");

DESCRIBE_METHOD_ACTION
get_describe_method_action()
.captures(&method_str)
.and_then(|captures| captures.get(1).map(|m| m.as_str().to_lowercase()))
.and_then(|method_name| match method_name.as_str() {
Expand Down
Loading

0 comments on commit 8ce70ea

Please sign in to comment.