rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
/// Generate a typed Settings struct with defaults.
#[macro_export]
macro_rules! settings {
    (
        $( $field:ident : $field_type:ty = $default:expr ),* $(,)?
    ) => {
        #[derive(Debug, Clone)]
        pub struct Settings {
            $( pub $field: $field_type, )*
        }

        impl ::std::default::Default for Settings {
            fn default() -> Self {
                Self {
                    $( $field: ($default).into(), )*
                }
            }
        }
    };
}

#[cfg(test)]
mod tests {
    mod basic_settings {
        crate::settings! {
            debug: bool = true,
            secret_key: String = "change-me",
            allowed_hosts: Vec<String> = vec![],
            language_code: String = "en-us",
            time_zone: String = "UTC",
            static_url: String = "/static/",
        }

        #[test]
        fn settings_macro_creates_struct() {
            let settings = Settings::default();

            assert!(settings.debug);
        }

        #[test]
        fn settings_macro_default_values() {
            let settings = Settings::default();

            assert!(settings.debug);
            assert_eq!(settings.secret_key, "change-me");
            assert!(settings.allowed_hosts.is_empty());
            assert_eq!(settings.language_code, "en-us");
            assert_eq!(settings.time_zone, "UTC");
            assert_eq!(settings.static_url, "/static/");
        }

        #[test]
        fn settings_macro_field_types() {
            let settings = Settings::default();

            fn assert_bool(_: bool) {}
            fn assert_string(_: &String) {}
            fn assert_string_vec(_: &Vec<String>) {}

            assert_bool(settings.debug);
            assert_string(&settings.secret_key);
            assert_string_vec(&settings.allowed_hosts);
            assert_string(&settings.language_code);
            assert_string(&settings.time_zone);
            assert_string(&settings.static_url);
        }

        #[test]
        fn settings_macro_override_values() {
            let settings = Settings {
                debug: false,
                secret_key: "production-secret".to_string(),
                allowed_hosts: vec!["example.com".to_string()],
                language_code: "fr-fr".to_string(),
                time_zone: "Europe/Paris".to_string(),
                static_url: "/assets/".to_string(),
            };

            assert!(!settings.debug);
            assert_eq!(settings.secret_key, "production-secret");
            assert_eq!(settings.allowed_hosts, vec!["example.com"]);
            assert_eq!(settings.language_code, "fr-fr");
            assert_eq!(settings.time_zone, "Europe/Paris");
            assert_eq!(settings.static_url, "/assets/");
        }

        #[test]
        fn settings_macro_vec_default() {
            let settings = Settings::default();

            assert_eq!(settings.allowed_hosts, Vec::<String>::new());
        }

        #[test]
        fn settings_macro_bool_default() {
            let settings = Settings::default();

            assert!(settings.debug);
        }
    }

    mod trailing_comma_settings {
        crate::settings! {
            debug: bool = false,
            secret_key: String = "test-key",
        }

        #[test]
        fn settings_macro_trailing_comma() {
            let settings = Settings::default();

            assert!(!settings.debug);
            assert_eq!(settings.secret_key, "test-key");
        }
    }
}