mirror of
https://github.com/Xevion/time-banner.git
synced 2025-12-06 01:16:36 -06:00
fix: solve easy clippy warnings
This commit is contained in:
4
build.rs
4
build.rs
@@ -145,8 +145,8 @@ fn generate_timezone_map() -> Result<(), BuildError> {
|
|||||||
let mut processed_count = 0;
|
let mut processed_count = 0;
|
||||||
let mut skipped_count = 0;
|
let mut skipped_count = 0;
|
||||||
|
|
||||||
for (_line_num, line_result) in reader.lines().enumerate() {
|
for line in reader.lines() {
|
||||||
let line = line_result?;
|
let line = line?;
|
||||||
|
|
||||||
match parse_timezone_line(&line)? {
|
match parse_timezone_line(&line)? {
|
||||||
Some((abbreviation, offset)) => {
|
Some((abbreviation, offset)) => {
|
||||||
|
|||||||
@@ -35,9 +35,11 @@ impl Rasterizer {
|
|||||||
|
|
||||||
pub fn render(&self, svg_data: Vec<u8>) -> Result<Vec<u8>, RenderError> {
|
pub fn render(&self, svg_data: Vec<u8>) -> Result<Vec<u8>, RenderError> {
|
||||||
let tree = {
|
let tree = {
|
||||||
let mut opt = usvg::Options::default();
|
let opt = usvg::Options {
|
||||||
opt.fontdb = std::sync::Arc::new(self.font_db.clone());
|
fontdb: std::sync::Arc::new(self.font_db.clone()),
|
||||||
let tree_result = usvg::Tree::from_data(&*svg_data, &opt);
|
..Default::default()
|
||||||
|
};
|
||||||
|
let tree_result = usvg::Tree::from_data(&svg_data, &opt);
|
||||||
if tree_result.is_err() {
|
if tree_result.is_err() {
|
||||||
return Err(RenderError {
|
return Err(RenderError {
|
||||||
message: Some("Failed to parse".to_string()),
|
message: Some("Failed to parse".to_string()),
|
||||||
|
|||||||
162
src/relative.rs
162
src/relative.rs
@@ -33,108 +33,101 @@ pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
|||||||
let mut value = Duration::zero();
|
let mut value = Duration::zero();
|
||||||
|
|
||||||
if let Some(raw_year) = capture.name("year") {
|
if let Some(raw_year) = capture.name("year") {
|
||||||
value = value
|
value += match raw_year.as_str().parse::<i64>() {
|
||||||
+ match raw_year.as_str().parse::<i64>() {
|
Ok(year) => {
|
||||||
Ok(year) => {
|
Duration::days(year * 365)
|
||||||
Duration::days(year * 365)
|
+ (if year > 0 {
|
||||||
+ (if year > 0 {
|
Duration::hours(6) * year as i32
|
||||||
Duration::hours(6) * year as i32
|
} else {
|
||||||
} else {
|
Duration::zero()
|
||||||
Duration::zero()
|
})
|
||||||
})
|
}
|
||||||
}
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse year from {} ({})",
|
||||||
"Could not parse year from {} ({})",
|
raw_year.as_str(),
|
||||||
raw_year.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_month) = capture.name("month") {
|
if let Some(raw_month) = capture.name("month") {
|
||||||
value = value
|
value += match raw_month.as_str().parse::<i32>() {
|
||||||
+ match raw_month.as_str().parse::<i32>() {
|
Ok(month) => Duration::months(month),
|
||||||
Ok(month) => Duration::months(month),
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse month from {} ({})",
|
||||||
"Could not parse month from {} ({})",
|
raw_month.as_str(),
|
||||||
raw_month.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_week) = capture.name("week") {
|
if let Some(raw_week) = capture.name("week") {
|
||||||
value = value
|
value += match raw_week.as_str().parse::<i64>() {
|
||||||
+ match raw_week.as_str().parse::<i64>() {
|
Ok(week) => Duration::days(7) * week as i32,
|
||||||
Ok(week) => Duration::days(7) * week as i32,
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse week from {} ({})",
|
||||||
"Could not parse week from {} ({})",
|
raw_week.as_str(),
|
||||||
raw_week.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_day) = capture.name("day") {
|
if let Some(raw_day) = capture.name("day") {
|
||||||
value = value
|
value += match raw_day.as_str().parse::<i64>() {
|
||||||
+ match raw_day.as_str().parse::<i64>() {
|
Ok(day) => Duration::days(day),
|
||||||
Ok(day) => Duration::days(day),
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse day from {} ({})",
|
||||||
"Could not parse day from {} ({})",
|
raw_day.as_str(),
|
||||||
raw_day.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_hour) = capture.name("hour") {
|
if let Some(raw_hour) = capture.name("hour") {
|
||||||
value = value
|
value += match raw_hour.as_str().parse::<i64>() {
|
||||||
+ match raw_hour.as_str().parse::<i64>() {
|
Ok(hour) => Duration::hours(hour),
|
||||||
Ok(hour) => Duration::hours(hour),
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse hour from {} ({})",
|
||||||
"Could not parse hour from {} ({})",
|
raw_hour.as_str(),
|
||||||
raw_hour.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_minute) = capture.name("minute") {
|
if let Some(raw_minute) = capture.name("minute") {
|
||||||
value = value
|
value += match raw_minute.as_str().parse::<i64>() {
|
||||||
+ match raw_minute.as_str().parse::<i64>() {
|
Ok(minute) => Duration::minutes(minute),
|
||||||
Ok(minute) => Duration::minutes(minute),
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse minute from {} ({})",
|
||||||
"Could not parse minute from {} ({})",
|
raw_minute.as_str(),
|
||||||
raw_minute.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_second) = capture.name("second") {
|
if let Some(raw_second) = capture.name("second") {
|
||||||
value = value
|
value += match raw_second.as_str().parse::<i64>() {
|
||||||
+ match raw_second.as_str().parse::<i64>() {
|
Ok(second) => Duration::seconds(second),
|
||||||
Ok(second) => Duration::seconds(second),
|
Err(e) => {
|
||||||
Err(e) => {
|
return Err(format!(
|
||||||
return Err(format!(
|
"Could not parse second from {} ({})",
|
||||||
"Could not parse second from {} ({})",
|
raw_second.as_str(),
|
||||||
raw_second.as_str(),
|
e
|
||||||
e.to_string()
|
))
|
||||||
))
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_sign) = capture.name("sign") {
|
if let Some(raw_sign) = capture.name("sign") {
|
||||||
@@ -148,6 +141,7 @@ pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::relative::{parse_duration, Months};
|
use crate::relative::{parse_duration, Months};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
|
|||||||
@@ -10,23 +10,18 @@ use crate::raster::Rasterizer;
|
|||||||
use crate::template::{render_template, OutputForm, RenderContext};
|
use crate::template::{render_template, OutputForm, RenderContext};
|
||||||
|
|
||||||
pub fn split_on_extension(path: &str) -> Option<(&str, &str)> {
|
pub fn split_on_extension(path: &str) -> Option<(&str, &str)> {
|
||||||
let split = path.rsplit_once('.');
|
let split = path.rsplit_once('.')?;
|
||||||
if split.is_none() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the file is not a dotfile (.env)
|
// Check that the file is not a dotfile (.env)
|
||||||
if split.unwrap().0.len() == 0 {
|
if split.0.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(split.unwrap())
|
Some(split)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_path(path: &str) -> (&str, &str) {
|
fn parse_path(path: &str) -> (&str, &str) {
|
||||||
split_on_extension(path)
|
split_on_extension(path).or(Some((path, "svg"))).unwrap()
|
||||||
.or_else(|| Some((path, "svg")))
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_rasterize(data: String, extension: &str) -> Result<(&str, Bytes), TimeBannerError> {
|
fn handle_rasterize(data: String, extension: &str) -> Result<(&str, Bytes), TimeBannerError> {
|
||||||
@@ -35,12 +30,9 @@ fn handle_rasterize(data: String, extension: &str) -> Result<(&str, Bytes), Time
|
|||||||
"png" => {
|
"png" => {
|
||||||
let renderer = Rasterizer::new();
|
let renderer = Rasterizer::new();
|
||||||
let raw_image = renderer.render(data.into_bytes());
|
let raw_image = renderer.render(data.into_bytes());
|
||||||
if raw_image.is_err() {
|
if let Err(err) = raw_image {
|
||||||
return Err(TimeBannerError::RasterizeError(
|
return Err(TimeBannerError::RasterizeError(
|
||||||
raw_image
|
err.message.unwrap_or_else(|| "Unknown error".to_string()),
|
||||||
.unwrap_err()
|
|
||||||
.message
|
|
||||||
.unwrap_or("Unknown error".to_string()),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,73 +47,33 @@ fn handle_rasterize(data: String, extension: &str) -> Result<(&str, Bytes), Time
|
|||||||
|
|
||||||
pub async fn index_handler() -> impl IntoResponse {
|
pub async fn index_handler() -> impl IntoResponse {
|
||||||
let epoch_now = Utc::now().timestamp();
|
let epoch_now = Utc::now().timestamp();
|
||||||
return Redirect::temporary(&*format!("/relative/{epoch_now}")).into_response();
|
|
||||||
|
Redirect::temporary(&format!("/relative/{epoch_now}")).into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn relative_handler(Path(path): Path<String>) -> impl IntoResponse {
|
pub async fn relative_handler(Path(path): Path<String>) -> impl IntoResponse {
|
||||||
let (raw_time, extension) = parse_path(path.as_str());
|
let (_raw_time, _extension) = parse_path(path.as_str());
|
||||||
|
|
||||||
|
get_error_response(TimeBannerError::NotFound).into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fallback_handler() -> impl IntoResponse {
|
pub async fn fallback_handler() -> impl IntoResponse {
|
||||||
return get_error_response(TimeBannerError::NotFound).into_response();
|
get_error_response(TimeBannerError::NotFound).into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn absolute_handler(Path(path): Path<String>) -> impl IntoResponse {
|
pub async fn absolute_handler(Path(path): Path<String>) -> impl IntoResponse {
|
||||||
let (raw_time, extension) = parse_path(path.as_str());
|
let (_raw_time, _extension) = parse_path(path.as_str());
|
||||||
|
|
||||||
|
get_error_response(TimeBannerError::NotFound).into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic handler that responds with a static string
|
// basic handler that responds with a static string
|
||||||
pub async fn implicit_handler(Path(path): Path<String>) -> impl IntoResponse {
|
pub async fn implicit_handler(Path(path): Path<String>) -> impl IntoResponse {
|
||||||
// Get extension if available
|
let (_raw_time, _extension) = parse_path(path.as_str());
|
||||||
let (raw_time, extension) = parse_path(path.as_str());
|
|
||||||
|
|
||||||
// Parse epoch
|
get_error_response(TimeBannerError::NotFound).into_response()
|
||||||
let parsed_epoch = raw_time.parse::<i64>();
|
}
|
||||||
if parsed_epoch.is_err() {
|
|
||||||
return get_error_response(TimeBannerError::ParseError(
|
fn parse_epoch_into_datetime(epoch: i64) -> Option<DateTime<Utc>> {
|
||||||
"Input could not be parsed into integer.".to_string(),
|
DateTime::from_timestamp(epoch, 0)
|
||||||
))
|
|
||||||
.into_response();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert epoch to DateTime
|
|
||||||
let naive_time = NaiveDateTime::from_timestamp_opt(parsed_epoch.unwrap(), 0);
|
|
||||||
if naive_time.is_none() {
|
|
||||||
return get_error_response(TimeBannerError::ParseError(
|
|
||||||
"Input was not a valid DateTime".to_string(),
|
|
||||||
))
|
|
||||||
.into_response();
|
|
||||||
}
|
|
||||||
|
|
||||||
let utc_time = DateTime::<Utc>::from_utc(naive_time.unwrap(), Utc);
|
|
||||||
|
|
||||||
// Build context for rendering
|
|
||||||
let context = RenderContext {
|
|
||||||
output_form: OutputForm::Relative,
|
|
||||||
value: utc_time,
|
|
||||||
tz_offset: utc_time.offset().fix(),
|
|
||||||
tz_name: "UTC",
|
|
||||||
view: "basic",
|
|
||||||
};
|
|
||||||
|
|
||||||
let rendered_template = render_template(context);
|
|
||||||
|
|
||||||
if rendered_template.is_err() {
|
|
||||||
return Response::builder()
|
|
||||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
|
||||||
.body(Body::from(format!(
|
|
||||||
"Template Could Not Be Rendered :: {}",
|
|
||||||
rendered_template.err().unwrap()
|
|
||||||
)))
|
|
||||||
.unwrap()
|
|
||||||
.into_response();
|
|
||||||
}
|
|
||||||
|
|
||||||
let rasterize_result = handle_rasterize(rendered_template.unwrap(), extension);
|
|
||||||
match rasterize_result {
|
|
||||||
Ok((mime_type, bytes)) => {
|
|
||||||
(StatusCode::OK, [(header::CONTENT_TYPE, mime_type)], bytes).into_response()
|
|
||||||
}
|
|
||||||
Err(e) => get_error_response(e).into_response(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user