mirror of
https://github.com/Xevion/time-banner.git
synced 2025-12-06 15:16:47 -06:00
chore: cargo fmt
This commit is contained in:
28
src/error.rs
28
src/error.rs
@@ -1,6 +1,6 @@
|
|||||||
use axum::http::{StatusCode};
|
use axum::http::StatusCode;
|
||||||
use axum::Json;
|
use axum::Json;
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub enum TimeBannerError {
|
pub enum TimeBannerError {
|
||||||
ParseError(String),
|
ParseError(String),
|
||||||
@@ -17,11 +17,25 @@ pub struct ErrorResponse {
|
|||||||
|
|
||||||
pub fn get_error_response(error: TimeBannerError) -> (StatusCode, Json<ErrorResponse>) {
|
pub fn get_error_response(error: TimeBannerError) -> (StatusCode, Json<ErrorResponse>) {
|
||||||
let (code, message) = match error {
|
let (code, message) = match error {
|
||||||
TimeBannerError::RenderError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("RenderError :: {}", msg)),
|
TimeBannerError::RenderError(msg) => (
|
||||||
TimeBannerError::ParseError(msg) => (StatusCode::BAD_REQUEST, format!("ParserError :: {}", msg)),
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
TimeBannerError::RasterizeError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, format!("RasterizeError :: {}", msg)),
|
format!("RenderError :: {}", msg),
|
||||||
TimeBannerError::NotFound => { (StatusCode::NOT_FOUND, "Not Found".to_string()) }
|
),
|
||||||
|
TimeBannerError::ParseError(msg) => {
|
||||||
|
(StatusCode::BAD_REQUEST, format!("ParserError :: {}", msg))
|
||||||
|
}
|
||||||
|
TimeBannerError::RasterizeError(msg) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("RasterizeError :: {}", msg),
|
||||||
|
),
|
||||||
|
TimeBannerError::NotFound => (StatusCode::NOT_FOUND, "Not Found".to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
(code, Json(ErrorResponse { code: code.as_u16(), message }))
|
(
|
||||||
|
code,
|
||||||
|
Json(ErrorResponse {
|
||||||
|
code: code.as_u16(),
|
||||||
|
message,
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use resvg::{tiny_skia, usvg};
|
|
||||||
use resvg::usvg::{fontdb, TreeParsing, TreeTextToPath};
|
use resvg::usvg::{fontdb, TreeParsing, TreeTextToPath};
|
||||||
|
use resvg::{tiny_skia, usvg};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RenderError {
|
pub struct RenderError {
|
||||||
@@ -26,16 +26,18 @@ impl Rasterizer {
|
|||||||
fontdb.load_system_fonts();
|
fontdb.load_system_fonts();
|
||||||
fontdb.load_fonts_dir("./fonts");
|
fontdb.load_fonts_dir("./fonts");
|
||||||
|
|
||||||
Self {
|
Self { font_db: fontdb }
|
||||||
font_db: fontdb
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 opt = usvg::Options::default();
|
let opt = usvg::Options::default();
|
||||||
let mut tree_result = usvg::Tree::from_data(&*svg_data, &opt);
|
let mut tree_result = usvg::Tree::from_data(&*svg_data, &opt);
|
||||||
if tree_result.is_err() { return Err(RenderError { message: Some("Failed to parse".to_string()) }); }
|
if tree_result.is_err() {
|
||||||
|
return Err(RenderError {
|
||||||
|
message: Some("Failed to parse".to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let tree = tree_result.as_mut().unwrap();
|
let tree = tree_result.as_mut().unwrap();
|
||||||
tree.convert_text(&self.font_db);
|
tree.convert_text(&self.font_db);
|
||||||
@@ -47,8 +49,8 @@ impl Rasterizer {
|
|||||||
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
|
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
|
||||||
tree.render(tiny_skia::Transform::default(), &mut pixmap.as_mut());
|
tree.render(tiny_skia::Transform::default(), &mut pixmap.as_mut());
|
||||||
|
|
||||||
pixmap
|
pixmap.encode_png().map_err(|_| RenderError {
|
||||||
.encode_png()
|
message: Some("Failed to encode".to_string()),
|
||||||
.map_err(|_| RenderError { message: Some("Failed to encode".to_string()) })
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
131
src/relative.rs
131
src/relative.rs
@@ -8,11 +8,12 @@ pub trait Months {
|
|||||||
|
|
||||||
impl Months for Duration {
|
impl Months for Duration {
|
||||||
fn months(count: i32) -> Self {
|
fn months(count: i32) -> Self {
|
||||||
Duration::milliseconds((Duration::days(1).num_milliseconds() as f64 * (365.25f64 / 12f64)) as i64) * count
|
Duration::milliseconds(
|
||||||
|
(Duration::days(1).num_milliseconds() as f64 * (365.25f64 / 12f64)) as i64,
|
||||||
|
) * count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref FULL_RELATIVE_PATTERN: Regex = Regex::new(concat!(
|
static ref FULL_RELATIVE_PATTERN: Regex = Regex::new(concat!(
|
||||||
"(?<sign>[-+])?",
|
"(?<sign>[-+])?",
|
||||||
@@ -22,7 +23,9 @@ lazy_static! {
|
|||||||
r"(?:(?<day>\d+)\s?(?:d|days?))?",
|
r"(?:(?<day>\d+)\s?(?:d|days?))?",
|
||||||
r"(?:(?<hour>\d+)\s?(?:h|hrs?|hours?))?",
|
r"(?:(?<hour>\d+)\s?(?:h|hrs?|hours?))?",
|
||||||
r"(?:(?<minute>\d+)\s?(?:m|mins?|minutes?))?",
|
r"(?:(?<minute>\d+)\s?(?:m|mins?|minutes?))?",
|
||||||
r"(?:(?<second>\d+)\s?(?:s|secs?|seconds?))?")).unwrap();
|
r"(?:(?<second>\d+)\s?(?:s|secs?|seconds?))?"
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
||||||
@@ -30,51 +33,107 @@ 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 + match raw_year.as_str().parse::<i64>() {
|
value = value
|
||||||
Ok(year) => Duration::days(year * 365) + (if year > 0 { Duration::hours(6) * year as i32 } else { Duration::zero() }),
|
+ match raw_year.as_str().parse::<i64>() {
|
||||||
Err(e) => return Err(format!("Could not parse year from {} ({})", raw_year.as_str(), e.to_string()))
|
Ok(year) => {
|
||||||
|
Duration::days(year * 365)
|
||||||
|
+ (if year > 0 {
|
||||||
|
Duration::hours(6) * year as i32
|
||||||
|
} else {
|
||||||
|
Duration::zero()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse year from {} ({})",
|
||||||
|
raw_year.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_month) = capture.name("month") {
|
if let Some(raw_month) = capture.name("month") {
|
||||||
value = value + match raw_month.as_str().parse::<i32>() {
|
value = value
|
||||||
|
+ match raw_month.as_str().parse::<i32>() {
|
||||||
Ok(month) => Duration::months(month),
|
Ok(month) => Duration::months(month),
|
||||||
Err(e) => return Err(format!("Could not parse month from {} ({})", raw_month.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse month from {} ({})",
|
||||||
|
raw_month.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_week) = capture.name("week") {
|
if let Some(raw_week) = capture.name("week") {
|
||||||
value = value + match raw_week.as_str().parse::<i64>() {
|
value = value
|
||||||
|
+ 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) => return Err(format!("Could not parse week from {} ({})", raw_week.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse week from {} ({})",
|
||||||
|
raw_week.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_day) = capture.name("day") {
|
if let Some(raw_day) = capture.name("day") {
|
||||||
value = value + match raw_day.as_str().parse::<i64>() {
|
value = value
|
||||||
|
+ match raw_day.as_str().parse::<i64>() {
|
||||||
Ok(day) => Duration::days(day),
|
Ok(day) => Duration::days(day),
|
||||||
Err(e) => return Err(format!("Could not parse day from {} ({})", raw_day.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse day from {} ({})",
|
||||||
|
raw_day.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_hour) = capture.name("hour") {
|
if let Some(raw_hour) = capture.name("hour") {
|
||||||
value = value + match raw_hour.as_str().parse::<i64>() {
|
value = value
|
||||||
|
+ match raw_hour.as_str().parse::<i64>() {
|
||||||
Ok(hour) => Duration::hours(hour),
|
Ok(hour) => Duration::hours(hour),
|
||||||
Err(e) => return Err(format!("Could not parse hour from {} ({})", raw_hour.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse hour from {} ({})",
|
||||||
|
raw_hour.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_minute) = capture.name("minute") {
|
if let Some(raw_minute) = capture.name("minute") {
|
||||||
value = value + match raw_minute.as_str().parse::<i64>() {
|
value = value
|
||||||
|
+ match raw_minute.as_str().parse::<i64>() {
|
||||||
Ok(minute) => Duration::minutes(minute),
|
Ok(minute) => Duration::minutes(minute),
|
||||||
Err(e) => return Err(format!("Could not parse minute from {} ({})", raw_minute.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse minute from {} ({})",
|
||||||
|
raw_minute.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(raw_second) = capture.name("second") {
|
if let Some(raw_second) = capture.name("second") {
|
||||||
value = value + match raw_second.as_str().parse::<i64>() {
|
value = value
|
||||||
|
+ match raw_second.as_str().parse::<i64>() {
|
||||||
Ok(second) => Duration::seconds(second),
|
Ok(second) => Duration::seconds(second),
|
||||||
Err(e) => return Err(format!("Could not parse second from {} ({})", raw_second.as_str(), e.to_string()))
|
Err(e) => {
|
||||||
|
return Err(format!(
|
||||||
|
"Could not parse second from {} ({})",
|
||||||
|
raw_second.as_str(),
|
||||||
|
e.to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +141,7 @@ pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
|||||||
match raw_sign.as_str() {
|
match raw_sign.as_str() {
|
||||||
"-" => value = -value,
|
"-" => value = -value,
|
||||||
"+" => (),
|
"+" => (),
|
||||||
_ => return Err(format!("Could not parse sign from {}", raw_sign.as_str()))
|
_ => return Err(format!("Could not parse sign from {}", raw_sign.as_str())),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +149,8 @@ pub fn parse_duration(str: &str) -> Result<Duration, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::relative::{parse_duration, Months};
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use crate::relative::{Months, parse_duration};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_empty() {
|
fn parse_empty() {
|
||||||
@@ -102,15 +161,37 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_composite() {
|
fn parse_composite() {
|
||||||
assert_eq!(parse_duration("1y2mon3w4d5h6m7s"), Ok(Duration::hours(365 * 24 + 6) + Duration::months(2) + Duration::days(3 * 7 + 4) + Duration::hours(5) + Duration::minutes(6) + Duration::seconds(7)));
|
assert_eq!(
|
||||||
assert_eq!(parse_duration("19year33weeks4d9min"), Ok(Duration::hours((365 * 24 + 6) * 19) + Duration::days(33 * 7 + 4) + Duration::minutes(9)));
|
parse_duration("1y2mon3w4d5h6m7s"),
|
||||||
|
Ok(Duration::hours(365 * 24 + 6)
|
||||||
|
+ Duration::months(2)
|
||||||
|
+ Duration::days(3 * 7 + 4)
|
||||||
|
+ Duration::hours(5)
|
||||||
|
+ Duration::minutes(6)
|
||||||
|
+ Duration::seconds(7))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_duration("19year33weeks4d9min"),
|
||||||
|
Ok(Duration::hours((365 * 24 + 6) * 19)
|
||||||
|
+ Duration::days(33 * 7 + 4)
|
||||||
|
+ Duration::minutes(9))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_year() {
|
fn parse_year() {
|
||||||
assert_eq!(parse_duration("1y"), Ok(Duration::days(365) + Duration::hours(6)));
|
assert_eq!(
|
||||||
assert_eq!(parse_duration("2year"), Ok(Duration::days(365 * 2) + Duration::hours(6 * 2)));
|
parse_duration("1y"),
|
||||||
assert_eq!(parse_duration("144years"), Ok(Duration::days(365 * 144) + Duration::hours(6 * 144)));
|
Ok(Duration::days(365) + Duration::hours(6))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_duration("2year"),
|
||||||
|
Ok(Duration::days(365 * 2) + Duration::hours(6 * 2))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
parse_duration("144years"),
|
||||||
|
Ok(Duration::days(365 * 144) + Duration::hours(6 * 144))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use chrono::{DateTime, FixedOffset, Utc};
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
use timeago::Formatter;
|
|
||||||
use tera::{Context, Tera};
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use tera::{Context, Tera};
|
||||||
|
use timeago::Formatter;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref TEMPLATES: Tera = {
|
static ref TEMPLATES: Tera = {
|
||||||
@@ -10,7 +10,7 @@ lazy_static! {
|
|||||||
let names: Vec<&str> = t.get_template_names().collect();
|
let names: Vec<&str> = t.get_template_names().collect();
|
||||||
println!("{} templates found ([{}]).", names.len(), names.join(", "));
|
println!("{} templates found ([{}]).", names.len(), names.join(", "));
|
||||||
t
|
t
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Parsing error(s): {}", e);
|
println!("Parsing error(s): {}", e);
|
||||||
::std::process::exit(1);
|
::std::process::exit(1);
|
||||||
@@ -37,11 +37,14 @@ pub fn render_template(context: RenderContext) -> Result<String, tera::Error> {
|
|||||||
let mut template_context = Context::new();
|
let mut template_context = Context::new();
|
||||||
let formatter = Formatter::new();
|
let formatter = Formatter::new();
|
||||||
|
|
||||||
template_context.insert("text", match context.output_form {
|
template_context.insert(
|
||||||
|
"text",
|
||||||
|
match context.output_form {
|
||||||
OutputForm::Relative => formatter.convert_chrono(context.value, Utc::now()),
|
OutputForm::Relative => formatter.convert_chrono(context.value, Utc::now()),
|
||||||
OutputForm::Absolute => context.value.to_rfc3339()
|
OutputForm::Absolute => context.value.to_rfc3339(),
|
||||||
}.as_str());
|
}
|
||||||
|
.as_str(),
|
||||||
|
);
|
||||||
|
|
||||||
TEMPLATES.render("basic.svg", &template_context)
|
TEMPLATES.render("basic.svg", &template_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user