1use chrono::{DateTime, offset};
16use snafu::Snafu;
17use tibba_error::Error as BaseError;
18use time::macros::format_description;
19use time::{OffsetDateTime, PrimitiveDateTime};
20
21pub fn format_datetime(datetime: PrimitiveDateTime) -> String {
22 let ts = datetime.assume_utc().unix_timestamp();
23 if let Some(value) = DateTime::from_timestamp(ts, 0) {
24 value.with_timezone(&offset::Local).to_string()
25 } else {
26 String::new()
27 }
28}
29
30pub fn parse_primitive_datetime(s: &str) -> Result<PrimitiveDateTime> {
31 let fmt_t = format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]");
32 let fmt_space = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
33 if let Ok(dt) = PrimitiveDateTime::parse(s, fmt_t) {
34 return Ok(dt);
35 }
36 if let Ok(dt) = PrimitiveDateTime::parse(s, fmt_space) {
37 return Ok(dt);
38 }
39 if let Ok(odt) = OffsetDateTime::parse(s, &time::format_description::well_known::Rfc3339) {
40 let utc = odt.to_offset(time::UtcOffset::UTC);
41 return Ok(PrimitiveDateTime::new(utc.date(), utc.time()));
42 }
43 Err(Error::InvalidDatetime {
44 value: s.to_string(),
45 })
46}
47
48type Result<T> = std::result::Result<T, Error>;
49
50#[derive(Debug, Snafu)]
51#[snafu(visibility(pub))]
52pub enum Error {
53 #[snafu(display("{source}"))]
54 Sqlx { source: sqlx::Error },
55 #[snafu(display("{source}"))]
56 Json { source: serde_json::Error },
57 #[snafu(display("Not supported function: {}", name))]
58 NotSupported { name: String },
59 #[snafu(display("Not found"))]
60 NotFound,
61 #[snafu(display("Invalid datetime: {value}"))]
62 InvalidDatetime { value: String },
63}
64
65impl From<Error> for BaseError {
66 fn from(val: Error) -> Self {
67 let err = match val {
68 Error::Sqlx { source } => BaseError::new(source)
69 .with_sub_category("sqlx")
70 .with_exception(true),
71 Error::Json { source } => BaseError::new(source)
72 .with_sub_category("json")
73 .with_exception(true),
74 Error::NotSupported { name } => {
75 BaseError::new(format!("Not supported function: {name}"))
76 .with_sub_category("not_supported")
77 .with_exception(true)
78 }
79 Error::NotFound => BaseError::new("Not found")
80 .with_sub_category("not_found")
81 .with_exception(true),
82 Error::InvalidDatetime { value } => {
83 BaseError::new(format!("Invalid datetime: {value}"))
84 .with_sub_category("invalid_datetime")
85 }
86 };
87 err.with_category("model")
88 }
89}
90
91mod configuration;
92mod model;
93mod schema;
94mod user;
95
96pub use configuration::*;
97pub use model::*;
98pub use schema::*;
99pub use user::*;