Skip to content

Commit 2bfa9f0

Browse files
committed
Make type of inner ast mutator nicer
1 parent 18f5378 commit 2bfa9f0

File tree

2 files changed

+273
-32
lines changed

2 files changed

+273
-32
lines changed

fuzzcheck/src/mutators/either.rs

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,243 @@ where
211211
}
212212
}
213213
}
214+
215+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
216+
pub enum Either3<A, B, C> {
217+
A(A),
218+
B(B),
219+
C(C),
220+
}
221+
impl<T, A, B, C> Mutator<T> for Either3<A, B, C>
222+
where
223+
T: Clone + 'static,
224+
A: Mutator<T>,
225+
B: Mutator<T>,
226+
C: Mutator<T>,
227+
{
228+
#[doc(hidden)]
229+
type Cache = Either3<A::Cache, B::Cache, C::Cache>;
230+
#[doc(hidden)]
231+
type MutationStep = Either3<A::MutationStep, B::MutationStep, C::MutationStep>;
232+
#[doc(hidden)]
233+
type ArbitraryStep = Either3<A::ArbitraryStep, B::ArbitraryStep, C::ArbitraryStep>;
234+
#[doc(hidden)]
235+
type UnmutateToken = Either3<A::UnmutateToken, B::UnmutateToken, C::UnmutateToken>;
236+
237+
#[doc(hidden)]
238+
#[inline]
239+
#[no_coverage]
240+
fn initialize(&self) {
241+
match self {
242+
Either3::A(m) => m.initialize(),
243+
Either3::B(m) => m.initialize(),
244+
Either3::C(m) => m.initialize(),
245+
}
246+
}
247+
248+
#[doc(hidden)]
249+
#[inline]
250+
#[no_coverage]
251+
fn default_arbitrary_step(&self) -> Self::ArbitraryStep {
252+
match self {
253+
Either3::A(m) => Either3::A(m.default_arbitrary_step()),
254+
Either3::B(m) => Either3::B(m.default_arbitrary_step()),
255+
Either3::C(m) => Either3::C(m.default_arbitrary_step()),
256+
}
257+
}
258+
259+
#[doc(hidden)]
260+
#[inline]
261+
#[no_coverage]
262+
fn is_valid(&self, value: &T) -> bool {
263+
match self {
264+
Either3::A(m) => m.is_valid(value),
265+
Either3::B(m) => m.is_valid(value),
266+
Either3::C(m) => m.is_valid(value),
267+
}
268+
}
269+
270+
#[doc(hidden)]
271+
#[inline]
272+
#[no_coverage]
273+
fn validate_value(&self, value: &T) -> Option<Self::Cache> {
274+
match self {
275+
Either3::A(m) => {
276+
let c = m.validate_value(value)?;
277+
Some(Either3::A(c))
278+
}
279+
Either3::B(m) => {
280+
let c = m.validate_value(value)?;
281+
Some(Either3::B(c))
282+
}
283+
Either3::C(m) => {
284+
let c = m.validate_value(value)?;
285+
Some(Either3::C(c))
286+
}
287+
}
288+
}
289+
290+
#[doc(hidden)]
291+
#[inline]
292+
#[no_coverage]
293+
fn default_mutation_step(&self, value: &T, cache: &Self::Cache) -> Self::MutationStep {
294+
match (self, cache) {
295+
(Either3::A(m), Either3::A(c)) => Either3::A(m.default_mutation_step(value, c)),
296+
(Either3::B(m), Either3::B(c)) => Either3::B(m.default_mutation_step(value, c)),
297+
(Either3::C(m), Either3::C(c)) => Either3::C(m.default_mutation_step(value, c)),
298+
_ => unreachable!(),
299+
}
300+
}
301+
302+
#[doc(hidden)]
303+
#[no_coverage]
304+
fn global_search_space_complexity(&self) -> f64 {
305+
match self {
306+
Either3::A(m) => m.global_search_space_complexity(),
307+
Either3::B(m) => m.global_search_space_complexity(),
308+
Either3::C(m) => m.global_search_space_complexity(),
309+
}
310+
}
311+
312+
#[doc(hidden)]
313+
#[inline]
314+
#[no_coverage]
315+
fn max_complexity(&self) -> f64 {
316+
match self {
317+
Either3::A(m) => m.max_complexity(),
318+
Either3::B(m) => m.max_complexity(),
319+
Either3::C(m) => m.max_complexity(),
320+
}
321+
}
322+
323+
#[doc(hidden)]
324+
#[inline]
325+
#[no_coverage]
326+
fn min_complexity(&self) -> f64 {
327+
match self {
328+
Either3::A(m) => m.min_complexity(),
329+
Either3::B(m) => m.min_complexity(),
330+
Either3::C(m) => m.min_complexity(),
331+
}
332+
}
333+
334+
#[doc(hidden)]
335+
#[inline]
336+
#[no_coverage]
337+
fn complexity(&self, value: &T, cache: &Self::Cache) -> f64 {
338+
match (self, cache) {
339+
(Either3::A(m), Either3::A(c)) => m.complexity(value, c),
340+
(Either3::B(m), Either3::B(c)) => m.complexity(value, c),
341+
(Either3::C(m), Either3::C(c)) => m.complexity(value, c),
342+
_ => unreachable!(),
343+
}
344+
}
345+
346+
#[doc(hidden)]
347+
#[inline]
348+
#[no_coverage]
349+
fn ordered_arbitrary(&self, step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(T, f64)> {
350+
match (self, step) {
351+
(Either3::A(m), Either3::A(s)) => m.ordered_arbitrary(s, max_cplx),
352+
(Either3::B(m), Either3::B(s)) => m.ordered_arbitrary(s, max_cplx),
353+
(Either3::C(m), Either3::C(s)) => m.ordered_arbitrary(s, max_cplx),
354+
_ => unreachable!(),
355+
}
356+
}
357+
358+
#[doc(hidden)]
359+
#[inline]
360+
#[no_coverage]
361+
fn random_arbitrary(&self, max_cplx: f64) -> (T, f64) {
362+
match self {
363+
Either3::A(m) => m.random_arbitrary(max_cplx),
364+
Either3::B(m) => m.random_arbitrary(max_cplx),
365+
Either3::C(m) => m.random_arbitrary(max_cplx),
366+
}
367+
}
368+
369+
#[doc(hidden)]
370+
#[inline]
371+
#[no_coverage]
372+
fn ordered_mutate(
373+
&self,
374+
value: &mut T,
375+
cache: &mut Self::Cache,
376+
step: &mut Self::MutationStep,
377+
subvalue_provider: &dyn crate::SubValueProvider,
378+
max_cplx: f64,
379+
) -> Option<(Self::UnmutateToken, f64)> {
380+
match (self, cache, step) {
381+
(Either3::A(m), Either3::A(c), Either3::A(s)) => {
382+
let (t, cplx) = m.ordered_mutate(value, c, s, subvalue_provider, max_cplx)?;
383+
Some((Either3::A(t), cplx))
384+
}
385+
(Either3::B(m), Either3::B(c), Either3::B(s)) => {
386+
let (t, cplx) = m.ordered_mutate(value, c, s, subvalue_provider, max_cplx)?;
387+
Some((Either3::B(t), cplx))
388+
}
389+
(Either3::C(m), Either3::C(c), Either3::C(s)) => {
390+
let (t, cplx) = m.ordered_mutate(value, c, s, subvalue_provider, max_cplx)?;
391+
Some((Either3::C(t), cplx))
392+
}
393+
_ => unreachable!(),
394+
}
395+
}
396+
397+
#[doc(hidden)]
398+
#[inline]
399+
#[no_coverage]
400+
fn random_mutate(&self, value: &mut T, cache: &mut Self::Cache, max_cplx: f64) -> (Self::UnmutateToken, f64) {
401+
match (self, cache) {
402+
(Either3::A(m), Either3::A(c)) => {
403+
let (t, cplx) = m.random_mutate(value, c, max_cplx);
404+
(Either3::A(t), cplx)
405+
}
406+
(Either3::B(m), Either3::B(c)) => {
407+
let (t, cplx) = m.random_mutate(value, c, max_cplx);
408+
(Either3::B(t), cplx)
409+
}
410+
(Either3::C(m), Either3::C(c)) => {
411+
let (t, cplx) = m.random_mutate(value, c, max_cplx);
412+
(Either3::C(t), cplx)
413+
}
414+
_ => unreachable!(),
415+
}
416+
}
417+
418+
#[doc(hidden)]
419+
#[inline]
420+
#[no_coverage]
421+
fn unmutate(&self, value: &mut T, cache: &mut Self::Cache, t: Self::UnmutateToken) {
422+
match (self, cache, t) {
423+
(Either3::A(m), Either3::A(c), Either3::A(t)) => {
424+
m.unmutate(value, c, t);
425+
}
426+
(Either3::B(m), Either3::B(c), Either3::B(t)) => {
427+
m.unmutate(value, c, t);
428+
}
429+
(Either3::C(m), Either3::C(c), Either3::C(t)) => {
430+
m.unmutate(value, c, t);
431+
}
432+
_ => unreachable!(),
433+
}
434+
}
435+
436+
#[doc(hidden)]
437+
#[inline]
438+
#[no_coverage]
439+
fn visit_subvalues<'a>(&self, value: &'a T, cache: &'a Self::Cache, visit: &mut dyn FnMut(&'a dyn Any, f64)) {
440+
match (self, cache) {
441+
(Either3::A(m), Either3::A(cache)) => {
442+
m.visit_subvalues(value, cache, visit);
443+
}
444+
(Either3::B(m), Either3::B(cache)) => {
445+
m.visit_subvalues(value, cache, visit);
446+
}
447+
(Either3::C(m), Either3::C(cache)) => {
448+
m.visit_subvalues(value, cache, visit);
449+
}
450+
_ => unreachable!(),
451+
}
452+
}
453+
}

fuzzcheck/src/mutators/grammar/mutators.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use fuzzcheck_mutators_derive::make_single_variant_mutator;
99
use super::grammar::Grammar;
1010
use crate::mutators::alternation::AlternationMutator;
1111
use crate::mutators::character_classes::CharacterMutator;
12-
use crate::mutators::either::Either;
12+
use crate::mutators::either::Either3;
1313
use crate::mutators::fixed_len_vector::FixedLenVecMutator;
1414
use crate::mutators::grammar::ast::AST;
1515
use crate::mutators::map::AndMapMutator;
@@ -46,20 +46,19 @@ make_single_variant_mutator! {
4646
}
4747
}
4848

49-
type InnerASTMutator = Either<
49+
type InnerASTMutator = Either3<
5050
AlternationMutator<AST, ASTMutator>,
51-
Either<
52-
ASTSingleVariant<
53-
Tuple1Mutator<CharacterMutator>,
54-
Tuple1Mutator<
55-
Either<
56-
FixedLenVecMutator<AST, RecurToMutator<ASTMutator>>,
57-
Either<FixedLenVecMutator<AST, ASTMutator>, VecMutator<AST, ASTMutator>>,
58-
>,
51+
ASTSingleVariant<
52+
Tuple1Mutator<CharacterMutator>,
53+
Tuple1Mutator<
54+
Either3<
55+
FixedLenVecMutator<AST, RecurToMutator<ASTMutator>>,
56+
FixedLenVecMutator<AST, ASTMutator>,
57+
VecMutator<AST, ASTMutator>,
5958
>,
6059
>,
61-
RecursiveMutator<ASTMutator>,
6260
>,
61+
RecursiveMutator<ASTMutator>,
6362
>;
6463

6564
/// A mutator created by [`grammar_based_ast_mutator`](crate::mutators::grammar::grammar_based_ast_mutator)
@@ -242,39 +241,43 @@ impl ASTMutator {
242241
#[no_coverage]
243242
fn token(m: CharacterMutator) -> Self {
244243
Self {
245-
inner: Box::new(Either::Right(Either::Left(ASTSingleVariant::Token(
246-
Tuple1Mutator::new(m),
247-
)))),
244+
inner: Box::new(Either3::B(ASTSingleVariant::Token(Tuple1Mutator::new(m)))),
248245
}
249246
}
250247
#[no_coverage]
251-
fn sequence(m: Either<FixedLenVecMutator<AST, ASTMutator>, VecMutator<AST, ASTMutator>>) -> Self {
248+
fn concatenation(m: FixedLenVecMutator<AST, ASTMutator>) -> Self {
252249
Self {
253-
inner: Box::new(Either::Right(Either::Left(ASTSingleVariant::Sequence(
254-
Tuple1Mutator::new(Either::Right(m)),
255-
)))),
250+
inner: Box::new(Either3::B(ASTSingleVariant::Sequence(Tuple1Mutator::new(Either3::B(
251+
m,
252+
))))),
253+
}
254+
}
255+
#[no_coverage]
256+
fn repetition(m: VecMutator<AST, ASTMutator>) -> Self {
257+
Self {
258+
inner: Box::new(Either3::B(ASTSingleVariant::Sequence(Tuple1Mutator::new(Either3::C(
259+
m,
260+
))))),
256261
}
257262
}
258263
#[no_coverage]
259264
fn alternation(m: AlternationMutator<AST, ASTMutator>) -> Self {
260265
Self {
261-
inner: Box::new(Either::Left(m)),
266+
inner: Box::new(Either3::A(m)),
262267
}
263268
}
264269
#[no_coverage]
265270
fn recur(m: RecurToMutator<ASTMutator>) -> Self {
266271
Self {
267-
inner: Box::new(Either::Right(Either::Left(ASTSingleVariant::Sequence(
268-
Tuple1Mutator::new(Either::Left(FixedLenVecMutator::new_without_inherent_complexity(vec![
269-
m,
270-
]))),
271-
)))),
272+
inner: Box::new(Either3::B(ASTSingleVariant::Sequence(Tuple1Mutator::new(Either3::A(
273+
FixedLenVecMutator::new_without_inherent_complexity(vec![m]),
274+
))))),
272275
}
273276
}
274277
#[no_coverage]
275278
fn recursive(m: impl FnMut(&Weak<Self>) -> Self) -> Self {
276279
Self {
277-
inner: Box::new(Either::Right(Either::Right(RecursiveMutator::new(m)))),
280+
inner: Box::new(Either3::C(RecursiveMutator::new(m))),
278281
}
279282
}
280283

@@ -306,14 +309,12 @@ impl ASTMutator {
306309
let m = Self::from_grammar_rec(g.clone(), others);
307310
ms.push(m);
308311
}
309-
Self::sequence(Either::Left(FixedLenVecMutator::new_without_inherent_complexity(ms)))
310-
}
311-
Grammar::Repetition(g, range) => {
312-
Self::sequence(Either::Right(VecMutator::new_without_inherent_complexity(
313-
Self::from_grammar_rec(g.clone(), others),
314-
range.start..=range.end - 1,
315-
)))
312+
Self::concatenation(FixedLenVecMutator::new_without_inherent_complexity(ms))
316313
}
314+
Grammar::Repetition(g, range) => Self::repetition(VecMutator::new_without_inherent_complexity(
315+
Self::from_grammar_rec(g.clone(), others),
316+
range.start..=range.end - 1,
317+
)),
317318
Grammar::Recurse(g) => {
318319
if let Some(m) = others.get(&g.as_ptr()) {
319320
Self::recur(RecurToMutator::from(m))

0 commit comments

Comments
 (0)