1#![allow(non_camel_case_types)]
2use crate::iter::StringIter;
3use crate::transformfn::TransformFn;
4use std::{
5 fmt::Display,
6 mem,
7 ops::{Add, AddAssign, BitOr, BitOrAssign, Mul, MulAssign},
8};
9
10#[derive(Clone, Debug, PartialEq)]
33pub enum Generator {
34 AlphaLower,
37
38 AlphaUpper,
40
41 Digit,
43
44 AlphaNumLower,
46
47 AlphaNumUpper,
49
50 HexUpper,
52
53 HexLower,
55
56 Char(char),
58
59 Str(String),
64
65 OneOf {
69 v: Vec<Generator>,
70 is_optional: bool,
71 },
72
73 RepeatedN(Box<Generator>, usize),
77
78 RepeatedMN(Box<Generator>, usize, usize),
82
83 Sequence(Vec<Generator>),
87
88 Transform {
90 inner: Box<Generator>,
91 transform_fn: TransformFn,
92 },
93
94 Empty,
96}
97
98impl Generator {
99 const ASCII_LOWER_A: u8 = 97;
100 const ASCII_UPPER_A: u8 = 65;
101 const ASCII_0: u8 = 48;
102
103 pub fn regex(&self) -> String {
107 use Generator::*;
108
109 match self {
110 AlphaLower => "[a-z]".into(),
111 AlphaUpper => "[A-Z]".into(),
112 Digit => "\\d".into(),
113 AlphaNumUpper => "[A-Z\\d]".into(),
114 AlphaNumLower => "[a-z\\d]".into(),
115 HexUpper => "[\\dA-F]".into(),
116 HexLower => "[\\da-f]".into(),
117 Char(c) => match c {
118 &'.' => "\\.".into(),
119 c => String::from(*c),
120 },
121 Str(s) => s.replace('.', "\\."),
122 OneOf { v, is_optional } => {
123 let regexes = v.iter().map(|a| a.regex()).collect::<Vec<_>>();
124 let mut grp = format!("({})", regexes.join("|"));
125 if *is_optional {
126 grp.push('?');
127 }
128 grp
129 }
130 RepeatedN(a, n) => a.regex() + "{" + &n.to_string() + "}",
131 RepeatedMN(a, m, n) => a.regex() + "{" + &m.to_string() + "," + &n.to_string() + "}",
132 Sequence(v) => {
133 let regexes = v.iter().map(|a| a.regex()).collect::<Vec<_>>();
134 regexes.join("")
135 }
136 Transform {
137 inner,
138 transform_fn: _,
139 } => inner.regex(),
140 Empty => String::new(),
141 }
142 }
143
144 pub fn len(&self) -> u128 {
146 use Generator::*;
147 match self {
148 AlphaLower | AlphaUpper => 26,
149 Digit => 10,
150 AlphaNumUpper | AlphaNumLower => 36,
151 HexUpper | HexLower => 16,
152
153 Char(_) | Str(_) => 1,
154
155 OneOf { v, is_optional } => {
156 v.iter().map(|a| a.len()).sum::<u128>() + if *is_optional { 1 } else { 0 }
158 }
159
160 RepeatedN(a, n) => a.len().pow(*n as u32),
163 RepeatedMN(a, m, n) => {
165 let base = a.len();
166 (*m..=*n).map(|i| base.pow(i as u32)).sum()
167 }
168
169 Sequence(v) => v.iter().map(|a| a.len()).product(),
170 Transform {
171 inner,
172 transform_fn: _,
173 } => inner.len(),
174 Empty => 1,
175 }
176 }
177
178 fn generate_on_top_of(&self, num: &mut u128, result: &mut String) {
180 use Generator::*;
181
182 match self {
183 AlphaLower => {
184 let i = (*num % 26) as u8;
185 *num /= 26;
186 let c: char = (Self::ASCII_LOWER_A + i).into();
187 result.push(c);
188 }
189 AlphaUpper => {
190 let i = (*num % 26) as u8;
191 *num /= 26;
192 let c: char = (Self::ASCII_UPPER_A + i).into();
193 result.push(c);
194 }
195 Digit => {
196 let i = (*num % 10) as u8;
197 *num /= 10;
198 let c: char = (Self::ASCII_0 + i).into();
199 result.push(c);
200 }
201 AlphaNumUpper => {
202 let i = (*num % 36) as u8;
203 *num /= 36;
204 let c: char = if i < 26 {
205 Self::ASCII_UPPER_A + i
206 } else {
207 Self::ASCII_0 + i - 26
208 }
209 .into();
210 result.push(c);
211 }
212 AlphaNumLower => {
213 let i = (*num % 36) as u8;
214 *num /= 36;
215 let c: char = if i < 26 {
216 Self::ASCII_LOWER_A + i
217 } else {
218 Self::ASCII_0 + i - 26
219 }
220 .into();
221 result.push(c);
222 }
223 HexUpper => {
224 let i = (*num % 16) as u8;
225 *num /= 16;
226 let c: char = if i < 10 {
227 Self::ASCII_0 + i
228 } else {
229 Self::ASCII_UPPER_A + i - 10
230 }
231 .into();
232 result.push(c);
233 }
234 HexLower => {
235 let i = (*num % 16) as u8;
236 *num /= 16;
237 let c: char = if i < 10 {
238 Self::ASCII_0 + i
239 } else {
240 Self::ASCII_LOWER_A + i - 10
241 }
242 .into();
243 result.push(c);
244 }
245 Char(c) => {
246 result.push(*c);
247 }
248 Str(s) => {
249 result.push_str(s);
250 }
251 OneOf { v, is_optional } => {
252 let v_len = self.len();
253
254 let new_num = *num / v_len;
257 *num %= v_len;
258
259 if *is_optional && *num == 0 {
260 } else {
262 if *is_optional {
263 *num -= 1;
264 }
265 for a in v {
266 let a_len = a.len() as u128;
267 if *num < a_len {
268 a.generate_on_top_of(num, result);
269 break;
270 } else {
271 *num -= a_len;
273 }
274 }
275 }
276
277 *num = new_num;
278 }
279 RepeatedN(a, n) => {
280 let mut parts = Vec::with_capacity(*n);
282 for _ in 0..*n {
283 let mut r = String::new();
284 a.generate_on_top_of(num, &mut r);
285 parts.push(r);
286 }
287 parts.reverse();
288 result.push_str(&parts.join(""));
289 }
290 RepeatedMN(a, m, n) => {
291 let mut parts = Vec::with_capacity(n - m + 1);
292 for _ in *m..=*n {
293 let mut r = String::new();
294 a.generate_on_top_of(num, &mut r);
295 parts.push(r);
296 }
297 parts.reverse();
298 result.push_str(&parts.join(""));
299 }
300 Sequence(v) => {
301 for a in v {
302 a.generate_on_top_of(num, result);
303 }
304 }
305 Transform {
306 inner,
307 transform_fn,
308 } => {
309 let mut r = String::new();
310 inner.generate_on_top_of(num, &mut r);
311 let r = (transform_fn.0)(r);
312 result.push_str(&r);
313 }
314 Empty => {}
315 }
316 }
317
318 pub fn generate_one(&self, num: u128) -> String {
322 let range = self.len();
323 assert!(num < range);
324
325 let mut num = num;
326
327 let mut result = String::new();
329 self.generate_on_top_of(&mut num, &mut result);
330 result
331 }
332
333 pub fn optional(self) -> Self {
337 use Generator::OneOf;
338 match self {
339 OneOf {
340 v,
341 is_optional: true,
342 } => OneOf {
343 v,
344 is_optional: true,
345 },
346 OneOf {
347 v,
348 is_optional: false,
349 } => OneOf {
350 v,
351 is_optional: true,
352 },
353 _ => OneOf {
354 v: vec![self],
355 is_optional: true,
356 },
357 }
358 }
359
360 pub fn generate_all(&self) -> StringIter {
362 self.into()
363 }
364
365 pub fn transform(self, f: fn(String) -> String) -> Self {
367 let transform_fn = TransformFn(Box::new(f));
368
369 Self::Transform {
370 inner: Box::new(self),
371 transform_fn,
372 }
373 }
374
375 pub fn visit_one<F>(&self, mut num: u128, mut cb: F)
382 where
383 F: FnMut(String),
384 {
385 let range = self.len();
386 assert!(num < range);
387
388 self.visit_exact_inner(&mut num, &mut cb);
389 }
390
391 fn visit_exact_inner<F>(&self, num: &mut u128, cb: &mut F)
393 where
394 F: FnMut(String),
395 {
396 use Generator::*;
397
398 match self {
399 AlphaLower => {
400 let i = (*num % 26) as u8;
401 *num /= 26;
402 let c: char = (Self::ASCII_LOWER_A + i).into();
403 cb(String::from(c));
404 }
405 AlphaUpper => {
406 let i = (*num % 26) as u8;
407 *num /= 26;
408 let c: char = (Self::ASCII_UPPER_A + i).into();
409 cb(String::from(c));
410 }
411 Digit => {
412 let i = (*num % 10) as u8;
413 *num /= 10;
414 let c: char = (Self::ASCII_0 + i).into();
415 cb(String::from(c));
416 }
417 AlphaNumUpper => {
418 let i = (*num % 36) as u8;
419 *num /= 36;
420 let c: char = if i < 26 {
421 Self::ASCII_UPPER_A + i
422 } else {
423 Self::ASCII_0 + i - 26
424 }
425 .into();
426 cb(String::from(c));
427 }
428 AlphaNumLower => {
429 let i = (*num % 36) as u8;
430 *num /= 36;
431 let c: char = if i < 26 {
432 Self::ASCII_LOWER_A + i
433 } else {
434 Self::ASCII_0 + i - 26
435 }
436 .into();
437 cb(String::from(c));
438 }
439 HexUpper => {
440 let i = (*num % 16) as u8;
441 *num /= 16;
442 let c: char = if i < 10 {
443 Self::ASCII_0 + i
444 } else {
445 Self::ASCII_UPPER_A + i - 10
446 }
447 .into();
448 cb(String::from(c));
449 }
450 HexLower => {
451 let i = (*num % 16) as u8;
452 *num /= 16;
453 let c: char = if i < 10 {
454 Self::ASCII_0 + i
455 } else {
456 Self::ASCII_LOWER_A + i - 10
457 }
458 .into();
459 cb(String::from(c));
460 }
461 Char(c) => cb(String::from(*c)),
462 Str(s) => cb(s.to_string()),
463 OneOf { v, is_optional } => {
464 let v_len = self.len();
465
466 let new_num = *num / v_len;
469 *num %= v_len;
470
471 if *is_optional && *num == 0 {
472 } else {
474 if *is_optional {
475 *num -= 1;
476 }
477 for a in v {
478 let a_len = a.len();
479 if *num < a_len {
480 a.visit_exact_inner(num, cb);
481 break;
482 } else {
483 *num -= a_len;
485 }
486 }
487 }
488
489 *num = new_num;
490 }
491 RepeatedN(a, n) => {
492 let mut parts = Vec::with_capacity(*n);
494 for _ in 0..*n {
495 let mut r = String::new();
496 a.generate_on_top_of(num, &mut r);
497 parts.push(r);
498 }
499
500 parts.into_iter().rev().for_each(cb);
501 }
502 RepeatedMN(a, m, n) => {
503 let mut parts = Vec::with_capacity(n - m + 1);
504 for _ in *m..=*n {
505 let mut r = String::new();
506 a.generate_on_top_of(num, &mut r);
507 parts.push(r);
508 }
509 parts.into_iter().rev().for_each(cb);
510 }
511 Sequence(v) => v.iter().for_each(|a| a.visit_exact_inner(num, cb)),
512 Transform {
513 inner,
514 transform_fn,
515 } => {
516 let mut r = String::new();
517 inner.generate_on_top_of(num, &mut r);
518 let r = (transform_fn.0)(r);
519 cb(r);
520 }
521 Empty => {}
523 }
524 }
525}
526
527impl Default for Generator {
528 fn default() -> Self {
529 Generator::Empty
530 }
531}
532
533impl From<char> for Generator {
534 fn from(c: char) -> Self {
535 Generator::Char(c)
536 }
537}
538
539impl From<&str> for Generator {
540 fn from(s: &str) -> Self {
541 Generator::Str(s.to_string())
542 }
543}
544
545impl From<String> for Generator {
546 fn from(s: String) -> Self {
547 Generator::Str(s)
548 }
549}
550
551impl<T> From<&[T]> for Generator
552where
553 T: AsRef<str> + Display,
554{
555 fn from(values: &[T]) -> Self {
556 let is_optional = false;
558 let v = values
559 .iter()
560 .map(|value| Generator::Str(value.to_string()))
561 .collect();
562 Generator::OneOf { v, is_optional }
563 }
564}
565
566impl BitOr for Generator {
567 type Output = Self;
568
569 fn bitor(self, rhs: Self) -> Self::Output {
570 use Generator::*;
571 match (self, rhs) {
572 (
573 OneOf {
574 v: mut v1,
575 is_optional: opt1,
576 },
577 OneOf {
578 v: v2,
579 is_optional: opt2,
580 },
581 ) => {
582 v1.extend(v2);
583
584 let is_optional = opt1 || opt2;
585 OneOf { v: v1, is_optional }
586 }
587 (OneOf { mut v, is_optional }, rhs) => {
588 v.push(rhs);
589 OneOf { v, is_optional }
590 }
591 (lhs, OneOf { mut v, is_optional }) => {
592 v.insert(0, lhs);
593 OneOf { v, is_optional }
594 }
595
596 (lhs, rhs) => {
597 let v = vec![lhs, rhs];
598 OneOf {
599 v,
600 is_optional: false,
601 }
602 }
603 }
604 }
605}
606
607impl Mul<usize> for Generator {
617 type Output = Self;
618
619 fn mul(self, rhs: usize) -> Self::Output {
620 if rhs == 0 {
621 Generator::Empty
623 } else {
624 let lhs = Box::new(self);
625 Generator::RepeatedN(lhs, rhs)
626 }
627 }
628}
629
630impl MulAssign<usize> for Generator {
631 fn mul_assign(&mut self, rhs: usize) {
632 if rhs == 0 {
633 *self = Generator::Empty;
635 } else {
636 let repeat = self.clone() * rhs;
637 *self = repeat;
638 }
639 }
640}
641
642impl Mul<(usize, usize)> for Generator {
648 type Output = Self;
649
650 fn mul(self, rhs: (usize, usize)) -> Self::Output {
651 let (m, n) = rhs;
652 assert!(m <= n);
653
654 let lhs = Box::new(self);
655 if m == 0 {
656 Generator::RepeatedMN(lhs, 1, n).optional()
658 } else {
659 Generator::RepeatedMN(lhs, m, n)
660 }
661 }
662}
663
664impl MulAssign<(usize, usize)> for Generator {
665 fn mul_assign(&mut self, rhs: (usize, usize)) {
666 let (m, n) = rhs;
667 assert!(m <= n);
668
669 let lhs = mem::take(self);
670
671 *self = if m == 0 {
672 Generator::RepeatedMN(Box::new(lhs), 1, n).optional()
673 } else {
674 Generator::RepeatedMN(Box::new(lhs), m, n)
675 };
676 }
677}
678
679impl Add for Generator {
689 type Output = Self;
690
691 fn add(self, rhs: Self) -> Self::Output {
692 use Generator::*;
693 match (self, rhs) {
694 (s, Generator::Empty) => s,
696 (Sequence(mut v1), Sequence(v2)) => {
697 v1.extend(v2);
698 Sequence(v1)
699 }
700 (Sequence(mut v1), rhs) => {
701 v1.push(rhs);
702 Sequence(v1)
703 }
704 (lhs, Sequence(v2)) => {
705 let mut v = Vec::with_capacity(1 + v2.len());
706 v.push(lhs);
707 v.extend(v2);
708 Sequence(v)
709 }
710
711 (lhs, rhs) => {
712 let v = vec![lhs, rhs];
713 Sequence(v)
714 }
715 }
716 }
717}
718
719impl AddAssign for Generator {
720 fn add_assign(&mut self, rhs: Self) {
721 use Generator::*;
722 match (self, rhs) {
723 (_, Generator::Empty) => {}
725 (Sequence(v1), Sequence(v2)) => {
726 v1.extend(v2);
727 }
728 (Sequence(v1), rhs) => {
729 v1.push(rhs);
730 }
731 (lhs, Sequence(v2)) => {
732 let mut v = Vec::with_capacity(1 + v2.len());
733 v.push(mem::take(lhs));
734 v.extend(v2);
735 *lhs = Sequence(v);
736 }
737
738 (lhs, rhs) => {
739 let left = mem::take(lhs);
740 let v = vec![left, rhs];
741 *lhs = Sequence(v)
742 }
743 }
744 }
745}
746
747impl BitOrAssign for Generator {
748 fn bitor_assign(&mut self, rhs: Self) {
749 use Generator::*;
750 match (self, rhs) {
751 (
752 OneOf {
753 v: v1,
754 is_optional: opt1,
755 },
756 OneOf {
757 v: v2,
758 is_optional: opt2,
759 },
760 ) => {
761 v1.extend(v2);
762 if opt2 {
763 *opt1 = true;
764 }
765 }
766 (OneOf { v, is_optional: _ }, rhs) => {
767 v.push(rhs);
768 }
769 (lhs, OneOf { mut v, is_optional }) => {
770 let left = mem::take(lhs);
771 v.insert(0, left);
772 *lhs = OneOf { v, is_optional };
773 }
774
775 (lhs, rhs) => {
776 let left = mem::take(lhs);
777 let v = vec![left, rhs];
778 *lhs = OneOf {
779 v,
780 is_optional: false,
781 };
782 }
783 }
784 }
785}
786
787macro_rules! impl_add_or {
788 ($t: ty) => {
789 impl Add<$t> for Generator {
790 type Output = Generator;
791
792 fn add(self, rhs: $t) -> Self::Output {
793 let rhs: Generator = rhs.into();
794 self + rhs
795 }
796 }
797
798 impl AddAssign<$t> for Generator {
799 fn add_assign(&mut self, rhs: $t) {
800 *self = std::mem::take(self) + rhs;
801 }
802 }
803
804 impl BitOr<$t> for Generator {
805 type Output = Generator;
806
807 fn bitor(self, rhs: $t) -> Self::Output {
808 let rhs: Generator = rhs.into();
809 self | rhs
810 }
811 }
812
813 impl BitOrAssign<$t> for Generator {
814 fn bitor_assign(&mut self, rhs: $t) {
815 *self = std::mem::take(self) | rhs;
816 }
817 }
818 };
819}
820
821impl_add_or!(String);
822impl_add_or!(&str);
823impl_add_or!(char);
824
825#[cfg(test)]
826mod tests {
827 use super::*;
828 use crate::{gen, oneof};
829 #[test]
830 fn combinations_consts() {
831 let eight_alphas = Generator::AlphaLower * 8;
832 assert_eq!(26u128.pow(8), eight_alphas.len());
833
834 let eight_alphas = Generator::AlphaLower * (8, 8);
836 assert_eq!(26u128.pow(8), eight_alphas.len());
837
838 let expected = 26u128.pow(7) + 26u128.pow(8);
841 let seven_or_eight_alphas = Generator::AlphaLower * (7, 8);
842 assert_eq!(expected, seven_or_eight_alphas.len());
843 }
844
845 #[test]
846 fn combinations_mn() {
847 let ab23 = (Generator::from("a") | Generator::from("b")) * (2, 3);
855 assert_eq!(12, ab23.len());
856 }
857
858 #[test]
859 fn combinations_str() {
860 let foo = Generator::from("foo");
861 assert_eq!(1, foo.len());
862 }
863
864 #[test]
865 fn combinations_oneof() {
866 let foo = Generator::from("foo");
867 let bar = Generator::from("bar");
868 assert_eq!(1, foo.len());
869 assert_eq!(1, bar.len());
870
871 let foo_bar = foo | bar;
872 assert_eq!(2, foo_bar.len());
873
874 let baz = Generator::from("baz");
875 assert_eq!(1, baz.len());
876 let foo_bar_baz = foo_bar | baz;
877 assert_eq!(3, foo_bar_baz.len());
878 }
879
880 #[test]
881 fn combinations_optional() {
882 let foo = Generator::from("foo");
883 let bar = Generator::from("bar");
884
885 let opt_foo = Generator::OneOf {
886 v: vec![foo.clone()],
887 is_optional: true,
888 };
889 assert_eq!(2, opt_foo.len());
890
891 let opt_foo_bar = Generator::OneOf {
892 v: vec![foo.clone(), bar.clone()],
893 is_optional: true,
894 };
895 assert_eq!(3, opt_foo_bar.len());
896
897 let mut v = opt_foo_bar.generate_all();
898 assert_eq!(Some("".into()), v.next());
899 assert_eq!(Some("foo".into()), v.next());
900 assert_eq!(Some("bar".into()), v.next());
901 assert_eq!(None, v.next());
902 }
903
904 #[test]
905 fn combinations_email() {
906 use Generator::Char;
907 let username = Generator::AlphaLower * (6, 8);
908 let user_combos = 26u128.pow(6) + 26u128.pow(7) + 26u128.pow(8);
909 assert_eq!(username.len(), user_combos);
910
911 let tld = Generator::from("com")
912 | Generator::from("net")
913 | Generator::from("org")
914 | Generator::from("edu")
915 | Generator::from("gov");
916 let tld_combos = 5;
917 assert_eq!(tld.len(), tld_combos);
918
919 let domain = Generator::AlphaLower * (1, 8) + Char('.') + tld;
920 let domain_combos = (1..=8).map(|i| 26u128.pow(i)).sum::<u128>() * tld_combos;
921 assert_eq!(domain.len(), domain_combos);
922
923 let email = username + Char('@') + domain;
924 assert_eq!(email.len(), domain_combos * user_combos);
925 }
926
927 #[test]
928 fn generate_alpha1() {
929 let alphas2 = Generator::AlphaLower * 2;
930 let aa = alphas2.generate_one(0);
931 assert_eq!(aa, "aa");
932
933 let onetwothree = (Generator::Digit * 10).generate_one(123);
934 assert_eq!(onetwothree, "0000000123");
935
936 let onetwothree = (Generator::Digit * 10)
938 .transform(|s| s.trim_start_matches('0').to_string())
939 .generate_one(123);
940 assert_eq!(onetwothree, "123");
941 }
942
943 #[test]
944 fn generate_hex() {
945 let hex = Generator::from("0x") + Generator::HexUpper * 8;
946
947 assert_eq!(4_294_967_296, hex.len());
948
949 assert_eq!(hex.generate_one(3_735_928_559), "0xDEADBEEF");
950 assert_eq!(hex.generate_one(464_375_821), "0x1BADD00D");
951 }
952
953 #[test]
954 fn simplify() {
955 let foo_opt1 = gen!("foo").optional();
956 let foo_opt1 = foo_opt1.optional(); let foo_opt2 = gen!("foo").optional();
959 assert_eq!(foo_opt1, foo_opt2);
960 }
961
962 #[test]
963 fn equality() {
964 let foo1 = Generator::from("foo");
966 let foo2 = gen!("foo");
967 assert_eq!(foo1, foo2);
968
969 let foo2 = oneof!("foo");
970 assert_eq!(foo1, foo2);
971
972 let foobar1 = oneof!("foo", "bar");
974 let mut foobar2 = gen!("foo");
975 foobar2 |= gen!("bar");
976 assert_eq!(foobar1, foobar2);
977
978 let foobar1 = gen!("foo") + gen!("bar");
980 let mut foobar2 = gen!("foo");
981 foobar2 += gen!("bar");
982 assert_eq!(foobar1, foobar2);
983
984 let foo1 = gen!("foo") * 2;
986 let mut foo2 = gen!("foo");
987 foo2 *= 2;
988 assert_eq!(foo1, foo2);
989
990 let foo1 = gen!("foo") * (2, 3);
992 let mut foo2 = gen!("foo");
993 foo2 *= (2, 3);
994 assert_eq!(foo1, foo2);
995 }
996
997 #[test]
998 fn test_reduce_optionals() {
999 let foo = gen!("foo").optional();
1002 let bar = gen!("bar").optional();
1003 let baz = gen!("baz").optional();
1004 let foobarbaz1 = foo | bar | baz;
1005
1006 let foobarbaz2 = gen!("foo").optional() | oneof!("bar", "baz");
1008
1009 assert_eq!(foobarbaz1, foobarbaz2);
1011
1012 let values: Vec<_> = foobarbaz1.generate_all().collect();
1014 assert_eq!(vec!["", "foo", "bar", "baz"], values);
1015
1016 let foobarbaz3 = gen!("foo") | gen!("bar").optional() | gen!("baz");
1018 assert_eq!(foobarbaz1, foobarbaz3);
1019 assert!(
1020 matches!(foobarbaz3, Generator::OneOf { v, is_optional } if v.len() == 3 && is_optional)
1021 );
1022 }
1023
1024 #[test]
1025 fn test_transform() {
1026 let foobarbaz = oneof!("foo", "bar", "baz");
1027
1028 let fooaraz = foobarbaz.clone().transform(|s| {
1030 if s.starts_with("b") {
1031 s.trim_start_matches('b').to_string()
1032 } else {
1033 s
1034 }
1035 });
1036
1037 assert_eq!(3, fooaraz.len());
1038 assert_eq!("foo", fooaraz.generate_one(0));
1039 assert_eq!("ar", fooaraz.generate_one(1));
1040 assert_eq!("az", fooaraz.generate_one(2));
1041
1042 let foobarbaz_upper = foobarbaz.clone().transform(|s| s.to_uppercase());
1044 assert_eq!(3, foobarbaz_upper.len());
1045 assert_eq!("FOO", foobarbaz_upper.generate_one(0));
1046 assert_eq!("BAR", foobarbaz_upper.generate_one(1));
1047 assert_eq!("BAZ", foobarbaz_upper.generate_one(2));
1048
1049 let ten_digits = Generator::Digit * 10;
1050 let onetwothree = ten_digits.generate_one(123);
1051 assert_eq!(onetwothree, "0000000123");
1052 let onetwothree = ten_digits
1053 .transform(|s| s.trim_start_matches('0').to_string())
1054 .generate_one(123);
1055 assert_eq!(onetwothree, "123");
1056 }
1057
1058 #[test]
1059 fn test_visit() {
1060 let foobarbaz = oneof!("foo", "bar", "baz");
1061 let fbb_nnnn = foobarbaz + Generator::Digit * 4;
1062
1063 let bar1234 = fbb_nnnn.generate_one(3703);
1064 assert_eq!("bar1234", bar1234);
1065
1066 let mut s = String::with_capacity(7);
1067 fbb_nnnn.visit_one(3703, |part| s.push_str(&part));
1068 assert_eq!("bar1234", s);
1069 }
1070
1071 #[test]
1072 fn regex() {
1073 let foobarbaz = oneof!("foo", "bar", "baz");
1074 let fbb_nnnn = foobarbaz + Generator::Digit * 4;
1075 assert_eq!("(foo|bar|baz)\\d{4}", fbb_nnnn.regex());
1076
1077 let hi45 = Generator::from("hi") * (4, 5);
1078 assert_eq!("hi{4,5}", hi45.regex());
1079
1080 let sea = Generator::from("Seattle") + gen!(", WA").optional();
1081 assert_eq!("Seattle(, WA)?", sea.regex());
1082 }
1083
1084 quickcheck! {
1085 fn street_addresses(n: u128) -> bool {
1087 const RANGE : u128 = 809_190_000;
1088
1089 let space = Generator::from(' ');
1090 let number = (Generator::Digit * (3, 5)).transform(|s| s.trim_start_matches('0').to_string());
1091
1092 let directional = space.clone() + oneof!("N", "E", "S", "W", "NE", "SE", "SW", "NW");
1093 let street_names = space.clone() + oneof!("Boren", "Olive", "Spring", "Cherry", "Seneca", "Yesler", "Madison", "James", "Union", "Mercer");
1094 let street_suffixes = space.clone() + oneof!("Rd", "St", "Ave", "Blvd", "Ln", "Dr", "Way", "Ct", "Pl");
1095
1096 let address = number
1097 + directional.clone().optional()
1098 + street_names
1099 + street_suffixes
1100 + directional.clone().optional();
1101
1102 assert_eq!(address.len(), RANGE);
1103 let n = n % RANGE;
1104
1105 let generated = address.generate_one(n);
1106
1107 let mut visited = String::with_capacity(generated.len());
1108 address.visit_one(n, |part| visited.push_str(&part));
1109 assert_eq!(visited, generated);
1110
1111 true
1112 }
1113 }
1114
1115 #[test]
1116 #[should_panic]
1117 fn exceeds_u128() {
1118 let g = Generator::Digit * 39;
1123
1124 let _n = g.len();
1126 }
1127
1128 #[test]
1129 fn lower_limit_0() {
1130 let g1 = Generator::Char('a') * (0, 2);
1132 let g2 = (Generator::Char('a') * (1, 2)).optional();
1133 assert_eq!(g1.len(), g2.len());
1134 assert_eq!(g1, g2);
1135
1136 let g1 = (Generator::Char('a') * (1, 2)) * 0;
1137 let g2 = Generator::Empty;
1138 assert_eq!(g1.len(), g2.len());
1139 assert_eq!(g1, g2);
1140 }
1141
1142 #[test]
1143 fn oneof_bitorassign_oneof() {
1144 let mut g = oneof!('a', 'b');
1145 g |= oneof!('x', 'y');
1146 assert_eq!(g.len(), 4);
1147 }
1148
1149 #[test]
1150 fn test_add_addassign() {
1151 let g = Generator::from("hello");
1152 let g = g + ',' + ' ' + "world!".to_string();
1153 assert_eq!(g.len(), 1);
1154
1155 let mut g = Generator::from("hello");
1156 g += ',';
1157 g += " world!";
1158
1159 assert_eq!(g.len(), 1);
1160 }
1161
1162 #[test]
1163 fn test_bitor_bitorassign() {
1164 let mut g = Generator::from("hello") | "hi" | "salut".to_string();
1165 g += ", ";
1166 g += Generator::from("world") | "tout le monde" | "everyone";
1167 g += '!';
1168
1169 assert_eq!(g.len(), 9);
1170 }
1171
1172 #[test]
1173 fn test_or_and() {
1174 let mut g = Generator::from("hello");
1175 g |= "salut";
1176 g += ',';
1177 g += " ";
1178 g += Generator::from("world") | "tout le monde" | "🌎";
1179 g += String::from("!");
1180
1181 assert_eq!(g.len(), 6);
1182 }
1183}