Skip to content

Commit e938f4d

Browse files
Simplify directive mutation (#967)
* Simplify directive mutation * Remove impl of DerefMut for Node because it obfuscates the possible clone happening under the hood * Add copy-on-write behaviour to doc comment --------- Co-authored-by: Renée Kooi <[email protected]>
1 parent ebe09fe commit e938f4d

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

crates/apollo-compiler/src/ast/impls.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,13 @@ impl DirectiveDefinition {
468468
self.arguments.iter().find(|argument| argument.name == name)
469469
}
470470

471+
/// Returns the definition of an argument by a given name.
472+
pub fn argument_by_name_mut(&mut self, name: &str) -> Option<&mut Node<InputValueDefinition>> {
473+
self.arguments
474+
.iter_mut()
475+
.find(|argument| argument.name == name)
476+
}
477+
471478
serialize_method!();
472479
}
473480

@@ -543,6 +550,17 @@ impl DirectiveList {
543550
self.0.iter().filter(move |dir| dir.name == name)
544551
}
545552

553+
/// Returns an iterator of mutable directives with the given name.
554+
///
555+
/// This method is best for repeatable directives.
556+
/// See also [`get`][Self::get] for non-repeatable directives.
557+
pub fn get_all_mut<'def: 'name, 'name>(
558+
&'def mut self,
559+
name: &'name str,
560+
) -> impl Iterator<Item = &'def mut Node<Directive>> + 'name {
561+
self.0.iter_mut().filter(move |dir| dir.name == name)
562+
}
563+
546564
/// Returns the first directive with the given name, if any.
547565
///
548566
/// This method is best for non-repeatable directives.
@@ -661,6 +679,18 @@ impl Directive {
661679
Argument::specified_argument_by_name(&self.arguments, name)
662680
}
663681

682+
/// Returns the value of the argument named `name`, as specified in the directive application.
683+
/// If there are other [`Node`] pointers to the same argument, this method will clone the
684+
/// argument using [`Node::make_mut`].
685+
///
686+
/// Returns `None` if the directive application does not specify this argument.
687+
///
688+
/// If the directive definition makes this argument nullable or defines a default value,
689+
/// consider using [`argument_by_name`][Self::argument_by_name] instead.
690+
pub fn specified_argument_by_name_mut(&mut self, name: &str) -> Option<&mut Node<Value>> {
691+
Argument::specified_argument_by_name_mut(&mut self.arguments, name)
692+
}
693+
664694
serialize_method!();
665695
}
666696

@@ -692,6 +722,15 @@ impl Argument {
692722
.iter()
693723
.find_map(|arg| (arg.name == name).then_some(&arg.value))
694724
}
725+
726+
pub(crate) fn specified_argument_by_name_mut<'doc>(
727+
arguments: &'doc mut [Node<Self>],
728+
name: &str,
729+
) -> Option<&'doc mut Node<Value>> {
730+
arguments
731+
.iter_mut()
732+
.find_map(|arg| (arg.name == name).then_some(&mut arg.make_mut().value))
733+
}
695734
}
696735

697736
impl OperationType {

0 commit comments

Comments
 (0)