Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ repository = "https://github.com/sqlpage/SQLPage"
documentation = "https://docs.rs/sqlpage"
include = ["/src", "/README.md", "/build.rs", "/sqlpage"]

[lints.rust]
elided_lifetimes_in_paths = "deny"
unreachable_pub = "deny"
unused_qualifications = "deny"

[lints.clippy]
pedantic = { level = "deny", priority = -1 }
missing_errors_doc = "allow"
missing_panics_doc = "allow"
dbg_macro = "deny"
todo = "deny"
unimplemented = "deny"

[profile.superoptimized]
inherits = "release"
strip = "debuginfo"
Expand Down
38 changes: 19 additions & 19 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,7 @@ async fn process_input_file(client: &awc::Client, path_out: &Path, original: Fil
.expect("Unable to write compressed frontend asset");
}

async fn copy_url_to_opened_file(
client: &awc::Client,
url: &str,
outfile: &mut impl std::io::Write,
) {
async fn copy_url_to_opened_file(client: &awc::Client, url: &str, outfile: &mut impl Write) {
// If the file has been downloaded manually, use it
let cached_file_path = make_url_path(url);
if !cached_file_path.exists() {
Expand All @@ -98,9 +94,9 @@ async fn copy_url_to_opened_file(
copy_cached_to_opened_file(&cached_file_path, outfile);
}

fn copy_cached_to_opened_file(source: &Path, outfile: &mut impl std::io::Write) {
let reader = std::fs::File::open(source).unwrap();
let mut buf = std::io::BufReader::new(reader);
fn copy_cached_to_opened_file(source: &Path, outfile: &mut impl Write) {
let reader = File::open(source).unwrap();
let mut buf = BufReader::new(reader);
// Not async, but performance should not really matter here
std::io::copy(&mut buf, outfile).unwrap();
}
Expand All @@ -112,17 +108,20 @@ async fn download_url_to_path(client: &awc::Client, url: &str, path: &Path) {
loop {
match client.get(url).send().await {
Ok(mut resp) => {
if resp.status() != 200 {
panic!("Received {} status code from {}", resp.status(), url);
}
assert!(
resp.status() == 200,
"Received {} status code from {}",
resp.status(),
url
);
let bytes = resp.body().limit(128 * 1024 * 1024).await.unwrap();
std::fs::write(path, &bytes)
.expect("Failed to write external frontend dependency to local file");
break;
}
Err(err) => {
if attempt >= max_attempts {
let path = make_url_path(url);
let path = make_url_path(url).display().to_string();
panic!(
"We need to download external frontend dependencies to build the static frontend. \n\
Could not download static asset after {max_attempts} attempts. You can manually download the file with: \n\
Expand Down Expand Up @@ -187,15 +186,16 @@ async fn download_tabler_icons(client: Rc<awc::Client>, sprite_url: &str) {
file.write_all(b"]").unwrap();
}

fn take_between<'a>(s: &mut &'a str, start: &str, end: &str) -> Option<&'a str> {
let start_index = s.find(start)?;
let end_index = s[start_index + start.len()..].find(end)?;
let result = &s[start_index + start.len()..][..end_index];
*s = &s[start_index + start.len() + end_index + end.len()..];
Some(result)
}

fn extract_icons_from_sprite(sprite_content: &[u8], mut callback: impl FnMut(&str, &str)) {
let mut sprite_str = std::str::from_utf8(sprite_content).unwrap();
fn take_between<'a>(s: &mut &'a str, start: &str, end: &str) -> Option<&'a str> {
let start_index = s.find(start)?;
let end_index = s[start_index + start.len()..].find(end)?;
let result = &s[start_index + start.len()..][..end_index];
*s = &s[start_index + start.len() + end_index + end.len()..];
Some(result)
}
while let Some(mut symbol_tag) = take_between(&mut sprite_str, "<symbol", "</symbol>") {
let id = take_between(&mut symbol_tag, "id=\"tabler-", "\"").expect("id not found");
let content_start = symbol_tag.find('>').unwrap() + 1;
Expand Down
6 changes: 3 additions & 3 deletions src/app_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ fn configuration_directory() -> PathBuf {
PathBuf::from("./sqlpage")
}

fn cannonicalize_if_possible(path: &std::path::Path) -> PathBuf {
fn cannonicalize_if_possible(path: &Path) -> PathBuf {
path.canonicalize().unwrap_or_else(|_| path.to_owned())
}

Expand Down Expand Up @@ -674,7 +674,7 @@ fn create_default_database(configuration_directory: &Path) -> String {

#[cfg(any(test, not(feature = "lambda-web")))]
fn encode_uri(path: &Path) -> std::borrow::Cow<'_, str> {
const ASCII_SET: &percent_encoding::AsciiSet = &percent_encoding::NON_ALPHANUMERIC
const ASCII_SET: &AsciiSet = &percent_encoding::NON_ALPHANUMERIC
.remove(b'-')
.remove(b'_')
.remove(b'.')
Expand Down Expand Up @@ -1000,7 +1000,7 @@ mod test {
let _lock = ENV_LOCK
.lock()
.expect("Another test panicked while holding the lock");
let temp_dir = std::env::temp_dir().join("sqlpage_test");
let temp_dir = env::temp_dir().join("sqlpage_test");
std::fs::create_dir_all(&temp_dir).unwrap();
let config_file_path = temp_dir.join("sqlpage.json");
let config_web_dir = temp_dir.join("config/web");
Expand Down
8 changes: 4 additions & 4 deletions src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub(crate) struct FileSystem {
}

impl FileSystem {
pub async fn init(local_root: impl Into<PathBuf>, db: &Database) -> Self {
pub(crate) async fn init(local_root: impl Into<PathBuf>, db: &Database) -> Self {
Self {
local_root: local_root.into(),
db_fs_queries: match DbFsQueries::init(db).await {
Expand All @@ -68,7 +68,7 @@ impl FileSystem {
}
}

pub async fn modified_since(
pub(crate) async fn modified_since(
&self,
app_state: &AppState,
access: FileAccess<'_>,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl FileSystem {
}
}

pub async fn read_to_string(
pub(crate) async fn read_to_string(
&self,
app_state: &AppState,
access: FileAccess<'_>,
Expand Down Expand Up @@ -127,7 +127,7 @@ impl FileSystem {
})
}

pub async fn read_file(
pub(crate) async fn read_file(
&self,
app_state: &AppState,
access: FileAccess<'_>,
Expand Down
5 changes: 1 addition & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#![deny(clippy::pedantic)]
#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]

//! [SQLPage](https://sql-page.com) is a high-performance web server that converts SQL queries
//! into dynamic web applications by rendering [handlebars templates](https://sql-page.com/custom_components.sql)
//! with data coming from SQL queries declared in `.sql` files.
Expand Down Expand Up @@ -135,7 +132,7 @@ impl AppState {
),
);

let oidc_state = crate::webserver::oidc::initialize_oidc_state(config).await?;
let oidc_state = webserver::oidc::initialize_oidc_state(config).await?;
let telemetry_metrics =
TelemetryMetrics::new(&db.connection, db.info.database_type.otel_name());

Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ fn init_logging() -> anyhow::Result<()> {
let otel_active = telemetry::init_telemetry()?;

match load_env {
Ok(path) => log::info!("Loaded environment variables from {path:?}"),
Ok(path) => log::info!("Loaded environment variables from {}", path.display()),
Err(dotenvy::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => log::debug!(
"No .env file found, using only environment variables and configuration files"
),
Expand Down
32 changes: 12 additions & 20 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ impl HeaderContext {
}

fn log(self, data: &JsonValue) -> anyhow::Result<PageContext> {
handle_log_component(&self.request_context.source_path, Option::None, data)?;
handle_log_component(&self.request_context.source_path, None, data)?;
Ok(PageContext::Header(self))
}

Expand Down Expand Up @@ -555,15 +555,15 @@ impl AnyRenderBodyContext {
}
}

pub struct JsonBodyRenderer<W: std::io::Write> {
pub struct JsonBodyRenderer<W: Write> {
writer: W,
is_first: bool,
prefix: &'static [u8],
suffix: &'static [u8],
separator: &'static [u8],
}

impl<W: std::io::Write> JsonBodyRenderer<W> {
impl<W: Write> JsonBodyRenderer<W> {
pub fn new_array(writer: W) -> JsonBodyRenderer<W> {
let mut renderer = Self {
writer,
Expand Down Expand Up @@ -741,7 +741,7 @@ impl CsvBodyRenderer {
}

#[allow(clippy::module_name_repetitions)]
pub struct HtmlRenderContext<W: std::io::Write> {
pub struct HtmlRenderContext<W: Write> {
app_state: Arc<AppState>,
pub writer: W,
current_component: Option<SplitTemplateRenderer>,
Expand All @@ -754,7 +754,7 @@ const DEFAULT_COMPONENT: &str = "table";
const PAGE_SHELL_COMPONENT: &str = "shell";
const FRAGMENT_SHELL_COMPONENT: &str = "shell-empty";

impl<W: std::io::Write> HtmlRenderContext<W> {
impl<W: Write> HtmlRenderContext<W> {
pub async fn new(
app_state: Arc<AppState>,
request_context: RequestContext,
Expand Down Expand Up @@ -1023,11 +1023,11 @@ fn handle_log_component(
Ok(())
}

struct HandlebarWriterOutput<W: std::io::Write>(W);
struct HandlebarWriterOutput<W: Write>(W);

impl<W: std::io::Write> handlebars::Output for HandlebarWriterOutput<W> {
impl<W: Write> handlebars::Output for HandlebarWriterOutput<W> {
fn write(&mut self, seg: &str) -> std::io::Result<()> {
std::io::Write::write_all(&mut self.0, seg.as_bytes())
Write::write_all(&mut self.0, seg.as_bytes())
}
}

Expand All @@ -1043,7 +1043,7 @@ pub struct SplitTemplateRenderer {
}

const _: () = assert!(
std::mem::size_of::<SplitTemplateRenderer>() <= 64,
size_of::<SplitTemplateRenderer>() <= 64,
"SplitTemplateRenderer should be small enough to be allocated on the stack"
);

Expand Down Expand Up @@ -1072,11 +1072,7 @@ impl SplitTemplateRenderer {
.unwrap_or_default()
}

fn render_start<W: std::io::Write>(
&mut self,
writer: W,
data: JsonValue,
) -> Result<(), RenderError> {
fn render_start<W: Write>(&mut self, writer: W, data: JsonValue) -> Result<(), RenderError> {
log::trace!(
"Starting rendering of a template{} with the following top-level parameters: {data}",
self.split_template
Expand Down Expand Up @@ -1108,11 +1104,7 @@ impl SplitTemplateRenderer {
Ok(())
}

fn render_item<W: std::io::Write>(
&mut self,
writer: W,
data: JsonValue,
) -> Result<(), RenderError> {
fn render_item<W: Write>(&mut self, writer: W, data: JsonValue) -> Result<(), RenderError> {
log::trace!("Rendering a new item in the page: {data:?}");
if let Some(local_vars) = self.local_vars.take() {
let mut render_context = handlebars::RenderContext::new(None);
Expand Down Expand Up @@ -1144,7 +1136,7 @@ impl SplitTemplateRenderer {
Ok(())
}

fn render_end<W: std::io::Write>(&mut self, writer: W) -> Result<(), RenderError> {
fn render_end<W: Write>(&mut self, writer: W) -> Result<(), RenderError> {
log::trace!(
"Closing a template {}",
self.split_template
Expand Down
4 changes: 2 additions & 2 deletions src/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -450,15 +450,15 @@ mod logfmt {
}

impl LogfmtLayer {
pub fn new() -> Self {
pub(super) fn new() -> Self {
Self {
stdout_colors: io::stdout().is_terminal(),
stderr_colors: io::stderr().is_terminal(),
output_mode: OutputMode::StdoutAndStderr,
}
}

pub fn test_writer() -> Self {
pub(super) fn test_writer() -> Self {
Self {
stdout_colors: false,
stderr_colors: false,
Expand Down
Loading