keelson_factory/
source.rs1use std::fmt;
2use std::sync::Arc;
3
4use keelson_models::Set;
5
6use crate::Faker;
7
8pub enum Source<T> {
23 Auto,
27 Value(T),
29 Null,
31 Omit,
33 Gen(Arc<dyn Fn(&mut Faker) -> T + Send + Sync>),
36}
37
38impl<T> Source<T> {
39 pub fn from_fn(g: impl Fn(&mut Faker) -> T + Send + Sync + 'static) -> Self {
41 Source::Gen(Arc::new(g))
42 }
43}
44
45impl<T: Clone> Source<T> {
46 pub fn resolve(&self, f: &mut Faker, auto: impl FnOnce(&mut Faker) -> Set<T>) -> Set<T> {
51 match self {
52 Source::Auto => auto(f),
53 Source::Value(v) => Set::Value(v.clone()),
54 Source::Null => Set::Null,
55 Source::Omit => Set::Unset,
56 Source::Gen(g) => Set::Value(g(f)),
57 }
58 }
59}
60
61#[allow(clippy::derivable_impls)]
64impl<T> Default for Source<T> {
65 fn default() -> Self {
66 Source::Auto
67 }
68}
69
70impl<T: Clone> Clone for Source<T> {
71 fn clone(&self) -> Self {
72 match self {
73 Source::Auto => Source::Auto,
74 Source::Value(v) => Source::Value(v.clone()),
75 Source::Null => Source::Null,
76 Source::Omit => Source::Omit,
77 Source::Gen(g) => Source::Gen(Arc::clone(g)),
78 }
79 }
80}
81
82impl<T: fmt::Debug> fmt::Debug for Source<T> {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 match self {
85 Source::Auto => f.write_str("Auto"),
86 Source::Value(v) => f.debug_tuple("Value").field(v).finish(),
87 Source::Null => f.write_str("Null"),
88 Source::Omit => f.write_str("Omit"),
89 Source::Gen(_) => f.write_str("Gen(..)"),
90 }
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 fn faker() -> Faker {
99 Faker::seeded(0)
100 }
101
102 #[test]
103 fn auto_defers_to_the_default_rule_in_both_directions() {
104 let s = Source::<i64>::Auto;
105 assert_eq!(s.resolve(&mut faker(), |_| Set::Value(7)), Set::Value(7));
106 assert_eq!(s.resolve(&mut faker(), |_| Set::Unset), Set::Unset);
107 }
108
109 #[test]
110 fn value_null_and_omit_map_onto_the_setter_states() {
111 assert_eq!(
112 Source::Value(3i64).resolve(&mut faker(), |_| Set::Unset),
113 Set::Value(3)
114 );
115 assert_eq!(
116 Source::<i64>::Null.resolve(&mut faker(), |_| Set::Value(1)),
117 Set::Null
118 );
119 assert_eq!(
120 Source::<i64>::Omit.resolve(&mut faker(), |_| Set::Value(1)),
121 Set::Unset
122 );
123 }
124
125 #[test]
126 fn gen_draws_from_the_faker_so_the_seed_covers_it() {
127 let s = Source::from_fn(|f: &mut Faker| f.i64_in(0, 1_000_000));
128 let a = s.resolve(&mut Faker::seeded(9), |_| Set::Unset);
129 let b = s.clone().resolve(&mut Faker::seeded(9), |_| Set::Unset);
130 assert_eq!(a, b, "same seed, same generated value");
131 assert!(matches!(a, Set::Value(_)));
132 }
133
134 #[test]
135 fn debug_names_the_variant_without_requiring_the_closure_to() {
136 assert_eq!(format!("{:?}", Source::<i64>::Auto), "Auto");
137 assert_eq!(
138 format!("{:?}", Source::from_fn(|f: &mut Faker| f.next_u64())),
139 "Gen(..)"
140 );
141 }
142}