samling/
helpers.rs

1use serde::{
2    de::{self, Deserialize, Deserializer, Visitor},
3    forward_to_deserialize_any,
4};
5
6use crate::deadpool_postgres::{self, Pool, Timeouts};
7use crate::Result;
8
9pub fn create_deadpool_manager(
10    db_host: String,
11    db_port: u16,
12    db_name: String,
13    db_user: String,
14    db_password: Option<String>,
15    max_db_connections: u32,
16) -> Result<Pool> {
17    let mut cfg = deadpool_postgres::Config::new();
18    cfg.user = Some(db_user);
19    cfg.password = db_password;
20    cfg.host = Some(db_host);
21    cfg.port = Some(db_port);
22    cfg.dbname = Some(db_name);
23    let builder = cfg
24        .builder(crate::tokio_postgres::NoTls)
25        .unwrap()
26        .max_size(max_db_connections as usize) // TODO: Do these really correspond?
27        .timeouts(Timeouts::wait_millis(30_000))
28        .runtime(deadpool_postgres::Runtime::Tokio1);
29    let pool = builder.build()?;
30    Ok(pool)
31}
32
33pub fn slugify(parts: &[&str]) -> String {
34    ::slug::slugify(parts.join(" "))
35}
36
37/// Returns the type's name, without module
38pub(crate) fn short_type_name<T>() -> &'static str {
39    std::any::type_name::<T>().rsplit_once(':').unwrap().1
40}
41
42/// Get the fields of a serde deserializable struct
43pub(crate) fn struct_fields<'de, T>() -> &'static [&'static str]
44where
45    T: Deserialize<'de>,
46{
47    struct StructFieldsDeserializer<'a> {
48        fields: &'a mut Option<&'static [&'static str]>,
49    }
50
51    impl<'de> Deserializer<'de> for StructFieldsDeserializer<'_> {
52        type Error = serde::de::value::Error;
53
54        fn deserialize_any<V>(self, _visitor: V) -> std::result::Result<V::Value, Self::Error>
55        where
56            V: Visitor<'de>,
57        {
58            Err(de::Error::custom("I'm just here for the fields"))
59        }
60
61        fn deserialize_struct<V>(
62            self,
63            _name: &'static str,
64            fields: &'static [&'static str],
65            visitor: V,
66        ) -> std::result::Result<V::Value, Self::Error>
67        where
68            V: Visitor<'de>,
69        {
70            *self.fields = Some(fields);
71            self.deserialize_any(visitor)
72        }
73
74        forward_to_deserialize_any! {
75            bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
76            byte_buf option unit unit_struct newtype_struct seq tuple
77            tuple_struct map enum identifier ignored_any
78        }
79    }
80
81    let mut fields = None;
82    let _ = T::deserialize(StructFieldsDeserializer {
83        fields: &mut fields,
84    });
85    fields.unwrap()
86}