extern crate engineer_derive;
pub use engineer_derive::*;
pub trait Builder<T>
where
T: Engineer,
T::Builder: Builder<T>,
{
fn done(self) -> T;
}
pub trait Engineer
where
Self: Sized,
Self::Builder: Builder<Self>,
{
const NORMAL_FIELDS: usize;
const OPTIONAL_FIELDS: usize;
type Builder;
type Params;
fn builder(required: Self::Params) -> Self::Builder;
fn build(required: Self::Params) -> Self {
Self::builder(required).done()
}
fn build_default() -> Self
where
Self::Params: Default,
{
Self::build(Default::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[allow(dead_code)]
#[derive(Debug, Default)]
enum Gender {
Male,
Female,
#[default]
NotSaying,
}
#[allow(dead_code)]
#[derive(Debug, Engineer)]
#[engineer(new, str_retype)]
struct User {
id: usize, first_name: String, #[engineer(default)]
gender: Gender, #[engineer(default_value = r#"String::from("fa")"#)]
lang_code: String, last_name: Option<String>, #[engineer(default)] is_educated: Option<bool>, #[engineer(default_value = "true")]
is_human: Option<bool>, }
#[test]
fn basic_test() {
let arash = User::new(1, "Arash").done();
assert_eq!(arash.id, 1);
assert_eq!(arash.first_name, "Arash");
assert_eq!(arash.last_name, None);
assert!(matches!(arash.gender, Gender::NotSaying));
assert_eq!(arash.lang_code, "fa".to_string());
assert!(matches!(arash.is_educated, Some(false)));
assert!(matches!(arash.is_human, Some(true)));
}
#[test]
fn basic_test_2() {
let model = User::new(1, "Monkey")
.last_name("Donkey")
.gender(Gender::NotSaying)
.lang_code("en")
.is_human(false)
.is_educated(true)
.done();
assert_eq!(model.id, 1);
assert_eq!(model.first_name, "Monkey");
assert_eq!(model.last_name, Some("Donkey".to_string()));
assert!(matches!(model.gender, Gender::NotSaying));
assert_eq!(model.lang_code, "en".to_string());
assert!(matches!(model.is_educated, Some(true)));
assert!(matches!(model.is_human, Some(false)));
}
}